bean的生命周期加载

来源:互联网 发布:哪个不是淘宝禁售商品 编辑:程序博客网 时间:2024/06/06 20:40

最近项目中使用到了一些bean生命周期的扩展接口,对各个接口实现类去实例化时的加载顺序产生了疑惑,项目中也有顺序的问题。所以梳理一下。


直接能百度到的bean声明周期的方法调用为:

1、Bean自身的方法:

  这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法

2、Bean级生命周期接口方法:

  这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法

3、容器级生命周期接口方法:

  这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。

4、工厂后处理器接口方法:

  这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器  接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

网上也各个接口的有加载顺序,但我发现,自己的项目加载顺序和网上所说的顺序不太一样,但网上的大家都赞同,肯定是自己哪里有区别:

于是先读一遍源码:

---------------bean加载源码分析-------------------

接口 :BeanDefinitionRegistryPostProcessorextends BeanFactoryPostProcessor
           解释:此接口是标准BeanFactoryPostProcesser的扩展,它是在BeanFactoryPostProcesser前一步
                     进行执行的。
      方法:postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
                解释:在bean标准的初始化后修改程序上下文中的bean定义注册。所有常规的bean定义都被加
                           载,但仍然没有实例化bean,此时允许进一步在下一个后置处理器来之前进行bean定义。
接口 :BeanFactoryPostProcessor
           解释:允许在程序上下文bean定义时进行自定义修改。一般在定义bean之后修改bean的属性配置,
                     此接口可以和bean定义进行交互,但此时bean还未进行实例化,违反了容器,可能会有意想不
                     到的副作用,如果需要和bean实例交互,考虑: BeanPostProcessor.
       方法:postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
                 解释:在上下文内的bean工厂里标准初始化之后修改bean。此时bean被加载,但没有实例化。
接口:ApplicationContextAware extends Aware
          解释:所有实现此接口的对象都希望在它运行时能得到通知 ApplicationContext。这个接口也可以被
                    对象去实现去获取资源文件,去发布应用程序,去获取MessageSource.然而它们有更具体的接口:          
                   ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware.
      方法:setApplicationContext(ApplicationContext applicationContext)
          解释:在该对象运行的时候设置上下文,通常这个调用将被用来初始化对象。
接口:BeanPostProcessor
         解释:允许自定义修改新bean实例,如:检查标记接口或包装代理。
      方法:postProcessBeforeInitialization(Object bean, String beanName) 
                解释:运用这个方法给新定义的bean实例回调接口之执行,例如:InitializingBean's
                           {@code afterPropertiesSet}或者自定义 init-method。这个bean此时已经填充了属性值,返回
                          的bean实例可能时原始的包装器。
     方法:postProcessAfterInitialization(Object bean, String beanName)
                解释:运用这个方法给新定义的bean实例回调接口之执行,例如:InitializingBean's
                           {@code afterPropertiesSet}或者自定义 init-method。这个bean此时已经填充了属性值,返回
                          的bean实例可能时原始的包装器。
                          在factoryBean中,调用这个回调将获取到factoryBean创建的实例和对象,这个后置处理
                          器能够决定是否运用FactoryBean或者创建对象或通过相应的bean检查。
接口:InitializingBean
          解释:继承了此接口的bean需要立即反应他们在BeanFactory中的属性,例如:执行自定义初始化,
                    或者仅仅是检查强制性属性设置。
     方法:afterPropertiesSet()
               解释:此方法被bean工厂调用来设置所有bean的属性,此方法只允许所有的bean属性设置并且配
                          置异常事件的错误配置之后bean实例化才能执行。
          其他bean级声明周期接口:BeanNameAware、BeanFactoryAware、DiposableBean
接口:InstantiationAwareBeanPostProcessor extends BeanPostProcessor
          解释:它是BeanPostProcessor的子接口,添加实例化之前的回调以及实例化之后的回调但是在明确                    
                    属性设置或自动装配之前。通常用于阻止特定目标bean的默认初始化,例如创建特殊目标的代理
                  (池目标,懒加载目标,等),这个接口是一个特殊的接口,一般在框架内部进行实例化使用,
   方法:postProcessBeforeInstantiation(Class<?> beanClass, String beanName);
          解释:此方法执行实在目标bean实例化之前,返回的对象可能是一个代理bean而不是目标bean,有
                    效地禁止了默认目标bean的实例化。如果这个方法返回的是一个非空对象,bean的创建过程将
                    会短路,唯一进一步处理的应用是通过{ @link # postProcessAfterInitialization } 从配置回调
                     { @link BeanPostProcessor BeanPostProcessors },这个回调仅适用于对一个bean类的定义,特别
                    地,它不适应用于多个bean的工厂方法。后处理器可以实现扩展
                     SmartInstantiationAwareBeanPostProcessor 接口,能够预测bean对象的类型,并返回到这里。
   方法:postProcessAfterInstantiation(Object bean, String beanName)
         解释:bean实例化之后执行的方法,但是在spring属性群(显示属性或者自动装配)之前发生。这是
                   一个理想的给bean实例进行执行注入字段的回调属性。如果属性群应该跳过,通常实现应该返回
                   true,返回false的话也将会阻止任何后续InstantiationAwareBeanPostProcessor实例调用这个bean实
                   例。
   方法:postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
          解释:在工厂给bean运用属性之前的后置处理器,允许检查是否所有的依赖像是满足的,例如基
                    于“Required”注解在bean属性上的setters.还允许替换属性值运用,通常通过创建一个新的
                    基于最初的MutablePropertyValues 实例,添加或删除特定的值。
          返回值: 真正给bean的属性值(能够传入PropertyValues实例),或者为null来跳过属性设置。

接口敲了敲继承这些接口的小demo,这里只贴上它们的加载顺序吧:


注意:上面的红色部分只有特殊类会执行,蓝色部分只有普通类实例化时才会执行。看下面:

发现:只要继承了BeanFactoryPostProcessor,BeanPostProcessor  这两个接口,它们的bean的加载都会在容器级接口

          以前就会完成,而且不会被其他bean生命周期接口实现类去回调。


spring的东西不熟,如有错误或缺漏的地方,希望能指正。