概念:Bean生命周期归IOC容器管理,IOC容器有两层,Applicationcontext和Beanfactory,前者面向开发者,提供了诸多丰富的api,后者面向底层,前者的实现是基于后者的。
一、各种接口方法分类
Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:
1、Bean自身的方法 : 这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法
2、Bean级生命周期接口方法 : 这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法
3、容器级生命周期接口方法 : 这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
4、工厂后处理器接口方法 : 这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。
二、基于BeanFactory的生命周期流转过程:
1、首先BeanFactoryPostProcessor类,是Bean工厂后处理器,是一个工厂类,用于生成容器级的BeanPostProcessor类。
2、BeanFactoryPostProcessor类的postProcessorBeanFactory方法构造出第一个容器级的BeanPostProcessor类。
3、然后实例化了InstantiationAwareBeanPostProcessorAdapter类,该类是
InstantiationAwareBeanPostProcessor类的实现类
4、然后调用了InstantiationAwareBeanPostProcessor类的postProcessorBeforeInstantiation方法,执行实例化Bean之前的操作。
5、然后是执行Bean的构造,实例化Bean,但是此时并没有执行指定的Bean的初始化方法(init-method),只是执行了构造方法。
6、然后执行InstantiationAwareBeanPostProcesser的postProcessorPropertyValue方法,即后处理器属性赋值方法,接下来就给Bean的属性赋值,即为属性注入,自动执行属性的set方法,此时也没用执行Bean的初始化方法。
7、然后紧接着调用Bean级别的两个方法BeanNameAware的setBeanName方法
和BeanFactoryAware的setBeanFactory方法。
前者为Bean赋予配置的名字,可能是xml中的id,可能是注解中指定的名字,不一定是类本身的类名。
后者则提供了Bean的工厂方法,也不知道是干啥用的,Bean都已经实例化了。传递的是Spring工厂自身。
如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文(同样这个方式也可以实现步骤4的内容,但比4更好,因为ApplicationContext是BeanFactory的子接口,有更多的实现方法);(springApplicationContext创建Bean有该步骤,BeanFactory创建Bean无该步骤)
8、然后另一个容器级别的类终于开始运行了,也就是BeanPostProcessor类,调用了它的postProcessorBeforeInitialization方法,该方法名与之前另一个容器级类的方法同名。它的作用是在Bean调用初始化方法之前执行写好的操作。
9、然后调用Bean级别的InitializationBean的afterProtertiesSet方法,从名字上看是属性注入后执行的方法,嗯,从前面属性注入后,执行这个方法,名字起的是对的。。
10、然后才真正执行Bean的初始化方法,init-method是在xml或注解中指定的。
此时Bean算是真正初始化完成了。
11、然后是执行容器级别的BeanPostProcessor的postProcessorAfterInitialization方法,即初始化后的后处理器执行方法。
11.5、此时若scope="prototype",则Bean返回给调用者,由调用者负责Bean的生命周期,spring不再管理这个Bean。
若此时scope="singleton",则Bean放入SPringIoc容器缓存池中,并将Bean的引用返回给调用者,spring继续对这些Bean进行后续的管理。
12、然后执行InstantiationAwareBeanPostProcessor的postProcessorAfterInitialization方法,即实例化后的后处理器执行方法。
两个容器级类的前后的后处理器的方法名是相同的。不同的是层次不同。
一个是在Bean实例化前后执行,一个是子Bean的初始化前后执行。
实例化里面嵌套着初始化方法。
13、容器执行成功后,可以在符合一定条件后销毁Bean,此时调用DiposibleBean的destory方法
最好调用xml或注解中指定的destory-method方法。
此时Bean生命周期结束。里面包含着容器级生命周期和Bean级生命周期。
——————————
在实例化前调用了容器级方法,实例化过程中调用的Bean级别方法。
容器级类的作用是全局的,对所有Bean都起作用,Bean级别的类在作用反复仅仅在当前Bean。
实例化过程包括通过容器级方法注入属性以及通过Bean级方法设置BeanName和BeanFactory。
然后初始化前调用了容器级方法,实例化过程中调用了afterProtertiesSet,即属性注入后执行的方法,然后才是Bean级别自己的初始化方法。
初始化之后调用容器级的初始化后处理器。
然后是容器级的实例化后处理器。
(后处理器可以注册多个,执行顺序必须实现Ordered接口。)
最后符合条件后执行Bean级别的销毁方法。
——————————————
探讨:
1、Spring对Bean进行了额外的控制,但是也使得Spring框架与Bean耦合在一起了,Spring一旦有改动,或者废弃某些方法,也许就需要修改大量代码。
因此尽可能的不用Spring提供的控制。其中对于InitializingBean和DisposableBean所实现的功能,与Bean自身提供的init-method和destory-method一样。使用自身提供的方法更有效的解耦。
2、除非开发基于Spring之上的插件或子项目,一般用不到Bean级别的四个接口及其方法。
BeanNameAware、BeanFactoryAware、InitializingBean和DisposableBean。
3、而BeanPostProcessor则相当于插件,为Bean提供逻辑,并且无需实现且继承。
——————————————
参考:
https://www.cnblogs.com/zrtqsk/p/3735273.html
https://blog.csdn.net/laiwenqiang/article/details/54693069
https://www.cnblogs.com/kenshinobiy/p/4652008.html
《精通SPring4.x——企业应用开发实战》