概念:Bean生命周期歸IOC容器管理,IOC容器有兩層,Applicationcontext和Beanfactory,前者面向開發(fā)者,提供了諸多豐富的api,后者面向底層,前者的實現(xiàn)是基于后者的。
一、各種接口方法分類
Bean的完整生命周期經(jīng)歷了各種方法調(diào)用,這些方法可以劃分為以下幾類:
1、Bean自身的方法 ?。骸 ∵@個包括了Bean本身調(diào)用的方法和通過配置文件中<bean>的init-method和destroy-method指定的方法
2、Bean級生命周期接口方法 ?。骸 ∵@個包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean這些接口的方法
3、容器級生命周期接口方法 ?。骸 ∵@個包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 這兩個接口實現(xiàn),一般稱它們的實現(xiàn)類為“后處理器”。
4、工廠后處理器接口方法 : 這個包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工廠后處理器接口的方法。工廠后處理器也是容器級的。在應(yīng)用上下文裝配配置文件之后立即調(diào)用。
二、基于BeanFactory的生命周期流轉(zhuǎn)過程:
1、首先BeanFactoryPostProcessor類,是Bean工廠后處理器,是一個工廠類,用于生成容器級的BeanPostProcessor類。
2、BeanFactoryPostProcessor類的postProcessorBeanFactory方法構(gòu)造出第一個容器級的BeanPostProcessor類。
3、然后實例化了InstantiationAwareBeanPostProcessorAdapter類,該類是
InstantiationAwareBeanPostProcessor類的實現(xiàn)類
4、然后調(diào)用了InstantiationAwareBeanPostProcessor類的postProcessorBeforeInstantiation方法,執(zhí)行實例化Bean之前的操作。
5、然后是執(zhí)行Bean的構(gòu)造,實例化Bean,但是此時并沒有執(zhí)行指定的Bean的初始化方法(init-method),只是執(zhí)行了構(gòu)造方法。
6、然后執(zhí)行InstantiationAwareBeanPostProcesser的postProcessorPropertyValue方法,即后處理器屬性賦值方法,接下來就給Bean的屬性賦值,即為屬性注入,自動執(zhí)行屬性的set方法,此時也沒用執(zhí)行Bean的初始化方法。
7、然后緊接著調(diào)用Bean級別的兩個方法BeanNameAware的setBeanName方法
和BeanFactoryAware的setBeanFactory方法。
前者為Bean賦予配置的名字,可能是xml中的id,可能是注解中指定的名字,不一定是類本身的類名。
后者則提供了Bean的工廠方法,也不知道是干啥用的,Bean都已經(jīng)實例化了。傳遞的是Spring工廠自身。
如果這個Bean已經(jīng)實現(xiàn)了ApplicationContextAware接口,會調(diào)用setApplicationContext(ApplicationContext)方法,傳入Spring上下文(同樣這個方式也可以實現(xiàn)步驟4的內(nèi)容,但比4更好,因為ApplicationContext是BeanFactory的子接口,有更多的實現(xiàn)方法);(springApplicationContext創(chuàng)建Bean有該步驟,BeanFactory創(chuàng)建Bean無該步驟)
8、然后另一個容器級別的類終于開始運行了,也就是BeanPostProcessor類,調(diào)用了它的postProcessorBeforeInitialization方法,該方法名與之前另一個容器級類的方法同名。它的作用是在Bean調(diào)用初始化方法之前執(zhí)行寫好的操作。
9、然后調(diào)用Bean級別的InitializationBean的afterProtertiesSet方法,從名字上看是屬性注入后執(zhí)行的方法,嗯,從前面屬性注入后,執(zhí)行這個方法,名字起的是對的。。
10、然后才真正執(zhí)行Bean的初始化方法,init-method是在xml或注解中指定的。
此時Bean算是真正初始化完成了。
11、然后是執(zhí)行容器級別的BeanPostProcessor的postProcessorAfterInitialization方法,即初始化后的后處理器執(zhí)行方法。
11.5、此時若scope="prototype",則Bean返回給調(diào)用者,由調(diào)用者負責(zé)Bean的生命周期,spring不再管理這個Bean。
若此時scope="singleton",則Bean放入SPringIoc容器緩存池中,并將Bean的引用返回給調(diào)用者,spring繼續(xù)對這些Bean進行后續(xù)的管理。
12、然后執(zhí)行InstantiationAwareBeanPostProcessor的postProcessorAfterInitialization方法,即實例化后的后處理器執(zhí)行方法。
兩個容器級類的前后的后處理器的方法名是相同的。不同的是層次不同。
一個是在Bean實例化前后執(zhí)行,一個是子Bean的初始化前后執(zhí)行。
實例化里面嵌套著初始化方法。
13、容器執(zhí)行成功后,可以在符合一定條件后銷毀Bean,此時調(diào)用DiposibleBean的destory方法
最好調(diào)用xml或注解中指定的destory-method方法。
此時Bean生命周期結(jié)束。里面包含著容器級生命周期和Bean級生命周期。
——————————
在實例化前調(diào)用了容器級方法,實例化過程中調(diào)用的Bean級別方法。
容器級類的作用是全局的,對所有Bean都起作用,Bean級別的類在作用反復(fù)僅僅在當(dāng)前Bean。
實例化過程包括通過容器級方法注入屬性以及通過Bean級方法設(shè)置BeanName和BeanFactory。
然后初始化前調(diào)用了容器級方法,實例化過程中調(diào)用了afterProtertiesSet,即屬性注入后執(zhí)行的方法,然后才是Bean級別自己的初始化方法。
初始化之后調(diào)用容器級的初始化后處理器。
然后是容器級的實例化后處理器。
(后處理器可以注冊多個,執(zhí)行順序必須實現(xiàn)Ordered接口。)
最后符合條件后執(zhí)行Bean級別的銷毀方法。
——————————————
探討:
1、Spring對Bean進行了額外的控制,但是也使得Spring框架與Bean耦合在一起了,Spring一旦有改動,或者廢棄某些方法,也許就需要修改大量代碼。
因此盡可能的不用Spring提供的控制。其中對于InitializingBean和DisposableBean所實現(xiàn)的功能,與Bean自身提供的init-method和destory-method一樣。使用自身提供的方法更有效的解耦。
2、除非開發(fā)基于Spring之上的插件或子項目,一般用不到Bean級別的四個接口及其方法。
BeanNameAware、BeanFactoryAware、InitializingBean和DisposableBean。
3、而BeanPostProcessor則相當(dāng)于插件,為Bean提供邏輯,并且無需實現(xiàn)且繼承。
——————————————
參考:
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——企業(yè)應(yīng)用開發(fā)實戰(zhàn)》