美文网首页
spring-生命周期

spring-生命周期

作者: 与诗小睡 | 来源:发表于2020-07-08 11:44 被阅读0次
  1. 四个阶段:

  2. 实例化 Instantiation

  3. 属性赋值 Populate

  4. 初始化 Initialization

  5. 销毁 Destruction

  6. 实例化 -> 属性赋值 -> 初始化 -> 销毁

  7. 主要逻辑都在doCreate()方法中,逻辑很清晰,就是顺序调用以下三个方法,这三个方法与三个生命周期阶段一一对应,

    1. createBeanInstance() -> 实例化

    2. populateBean() -> 属性赋值

    3. initializeBean() -> 初始化

    4. // 忽略了无关代码
      protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {
      
         // Instantiate the bean.
         BeanWrapper instanceWrapper = null;
         if (instanceWrapper == null) {
             // 实例化阶段!
            instanceWrapper = createBeanInstance(beanName, mbd, args);
         }
      
         // Initialize the bean instance.
         Object exposedObject = bean;
         try {
             // 属性赋值阶段!
            populateBean(beanName, mbd, instanceWrapper);
             // 初始化阶段!
            exposedObject = initializeBean(beanName, exposedObject, mbd);
         }
      
         
         }
      

常用扩展点

​ Spring生命周期相关的常用扩展点非常多,所以问题不是不知道,而是记不住或者记不牢。其实记不住的根本原因还是不够了解,这里通过源码+分类的方式帮大家记忆

  • BeanPostProcessor
  • InstantiationAwareBeanPostProcessor

这两兄弟可能是Spring扩展中最重要的两个接口!InstantiationAwareBeanPostProcessor作用于实例化阶段的前后,BeanPostProcessor作用于初始化阶段的前后。正好和第一、第三个生命周期阶段对应。通过图能更好理解

[图片上传失败...(image-e9f0e6-1594179888705)]

InstantiationAwareBeanPostProcessor实际上继承了BeanPostProcessor接口,严格意义上来看他们不是两兄弟,而是两父子。但是从生命周期角度我们重点关注其特有的对实例化阶段的影响,图中省略了从BeanPostProcessor继承的方法。

InstantiationAwareBeanPostProcessor extends BeanPostProcessor

第二大类:只调用一次的接口:

这一大类接口的特点是功能丰富,常用于用户自定义扩展。
第二大类中又可以分为两类

  • Aware类型的接口
  • 生命周期接口
无所不知的Aware

​ Aware类型的接口的作用就是让我们能够拿到Spring容器中的一些资源。基本都能够见名知意,Aware之前的名字就是可以拿到什么资源,例如BeanNameAware可以拿到BeanName,以此类推。调用时机需要注意:所有的Aware方法都是在初始化阶段之前调用的!
Aware接口众多,这里同样通过分类的方式帮助大家记忆。

Aware接口具体可以分为两组,至于为什么这么分,详见下面的源码分析。如下排列顺序同样也是Aware接口的执行顺序,能够见名知意的接口不再解释。

Aware Group1

  • BeanNameAware
  • BeanClassLoaderAware
  • BeanFactoryAware

Aware Group2

  • EnvironmentAware

  • EmbeddedValueResolverAware 这个知道的人可能不多,实现该接口能够获取Spring EL解析器,用户的自定义注解需要支持spel表达式的时候可以使用,非常方便。

  • ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware) 这几个接口可能让人有点懵,实际上这几个接口可以一起记,其返回值实质上都是当前的ApplicationContext对象,因为ApplicationContext是一个复合接口

    public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
           MessageSource, ApplicationEventPublisher, ResourcePatternResolver {}
    
    简单的两个生命周期接口
    • 至于剩下的两个生命周期接口就很简单了,实例化和属性赋值都是Spring帮助我们做的,能够自己实现的有初始化和销毁两个生命周期阶段
      • nitializingBean 对应生命周期的初始化阶段,在上面源码的invokeInitMethods(beanName, wrappedBean, mbd);方法中调用。有一点需要注意,因为Aware方法都是执行在初始化方法之前,所以可以在初始化方法中放心大胆的使用Aware接口获取的资源,这也是我们自定义扩展Spring的常用方式。
        除了实现InitializingBean接口之外还能通过注解或者xml配置的方式指定初始化方法,至于这几种定义方式的调用顺序其实没有必要记。因为这几个方法对应的都是同一个生命周期,只是实现方式不同,我们一般只采用其中一种方式。
      • DisposableBean 类似于InitializingBean,对应生命周期的销毁阶段,以ConfigurableApplicationContext#close()方法作为入口,实现是通过循环取所有实现了DisposableBean接口的Bean然后调用其destroy()方法 。感兴趣的可以自行跟一下源码。
  • 执行顺序
    • BeanPostProcessor有很多个,而且每个BeanPostProcessor都影响多个Bean,其执行顺序至关重要,必须能够控制其执行顺序才行。关于执行顺序这里需要引入两个排序相关的接口:PriorityOrdered、Ordered
    • PriorityOrdered是一等公民,首先被执行,PriorityOrdered公民之间通过接口返回值排序
    • Ordered是二等公民,然后执行,Ordered公民之间通过接口返回值排序

总结:

​ Spring Bean的生命周期分为四个阶段多个扩展点。扩展点又可以分为影响多个Bean影响单个Bean。整理如下

  • 实例化 Instantiation
  • 属性赋值 Populate
  • 初始化 Initialization
  • 销毁 Destruction

多个扩展点

  • 影响多个Bean

    • BeanPostProcessor
    • InstantiationAwareBeanPostProcessor
  • 影响单个Bean:

    • Aware

      • Aware Group1
        • BeanNameAware
        • BeanClassLoaderAware
        • BeanFactoryAware
      • Aware Group2
        • EnvironmentAware
        • EmbeddedValueResolverAware
        • ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware)

      生命周期

      • InitializingBean
      • DisposableBean

相关文章

网友评论

      本文标题:spring-生命周期

      本文链接:https://www.haomeiwen.com/subject/vgiqcktx.html