Spring在bean的創建過程中9次執行後置處理器BeanPostProcessor

從AbstractAutowireCapableBeanFactory 的createbean方法開始

 

其中的createBean方法是單例對象從BeanDefinition到bean實例的實際方法

 

beanPostProcess只是頂層接口,它會貫穿所有spring的bean的實例化和初始化的階段

 

第一次執行:

要不要走bean的創建流程,要麼接着往下走流程創建bean要麼返回程序員給的對象,直接返回

 

resolveBeforeInstantiation ,獲取所有後置處理器,判斷是否爲InstantiationAwareBeanPostProcessor實現類型,調用的方法

InstantiationAwareBeanPostProcessor的 postProcessBeforeInstantiation

這個後置處理器很關鍵,InstantiationAwareBeanPostProcessor有3個方法,第一個方法postProcessBeforeInstantiation如果你直接返回一個“自建對象”的話,那spring上下文直接就會把你的這個對象放入容器中,並執行BeanPostProcessor的postProcessAfterInitialization方法。如果第一個方法返回爲null,則spring創建bean的流程會繼續執行,會在populateBean方法中繼續調用postProcessAfterInstantiation和postProcessPropertyValues來進行屬性的裝配。

如果配置文件加了@EnableAspectJAutoProxy註解,就會import功能註冊一個InstantiationAwareBeanPostProcessor的子類AnnotationAwareAspectJAutoProxyCreator進行類的過濾,出現@AspectJ的類標記爲不需要代理的類,會被放入map中。

 

第二次:決定創建實例用哪個構造方法,此處完成之後就立馬反射用構造方法創建出還未初始化的對象了

 

在createBeanInstance中的determineConstructorsFromBeanPostProcessors方法中,判斷是否爲SmartInstantiationAwareBeanPostProcessor類型的後置處理器,調用的方法是:determineCandidateConstructors,這個方法用來推斷構造函數,看用哪個構造函數實例對象,實際使用的實現SmartInstantiationAwareBeanPostProcessor接口的AutowiredAnnotationBeanPostProcess後置處理器去做的。

 

 

第三次:解析並緩存註解信息,方便後邊使用

在createBeanInstance中的applyMergedBeanDefinitionPostProcessors方法中,判斷爲MergedBeanDefinitionPostProcessor,調用的方法是:postProcessMergedBeanDefinition,目的是用來緩存註解信息,方便後續使用  包括三個後置處理器

CommonAnnotationBeanPostProcessor處理並緩存

@PostConstruct @PreDestroy@WebServiceRef, @EJB, @Resource   

 

AutowiredAnnotationBeanPostProcessor處理並緩存

@Autowired

ApplicationListenerDetector很簡單,將beanName和是否是singleton的boolean變量放到ApplicationListenerDetector對象的Map<String, Boolean> singletonNames中

 

第四次:爲解決循環依賴中,對象提早暴露的問題,一般情況下直接暴漏出來,在有aop動態代理時提前返回代理後的對象,此處有個小瑕疵,雖然代碼實在這,實際執行時在populateBean()的屬性注入中

 

 

 

第五個方法:判斷是否要進行屬性的依賴注入 一般情況下都是true 

在populateBean中的會調用InstantiationAwareBeanPostProcessor這個處理器,調用的方法是:postProcessAfterInstantiation 

第六個方法:進行屬性的依賴注入

在populateBean中的又會調用InstantiationAwareBeanPostProcessor這個處理器,但是調用的方法是postProcessPropertyValues

這裏幹活的有兩個 ,CommonAnnotationBeanPostProcessor和AutowiredAnnotationBeanPostProcessor。前者處理@Resource註解,後者處理@Autowired註解

最終都是由

 beanFactory.resolveDependency()來找到需要的實例來注入,如果屬性實例還沒有被創建就先創建,這裏面就會有循環依賴的問題,這時候第四次的處理就發揮價值了,思路就是把實例化後、還沒初始化、正在創建中的(這幾個描述比較重要)對象放在一個map中暴露出來,先關聯上再說,等屬性實例創造好後,再注入

第七個方法:依次回調bean後置處理器的postProcessBeforeInitialization方法

主要有以下三個

 1.ApplicationContextAwareProcessor

ApplicationContextAwareProcessor依靠它內部invokeAwareInterfaces方法實現了以下Aware接口bean的初始化工作

2  ImportAwareBeanPostProcessor

 如果實現了ImportAware接口,在postProcessBeforeInitialization中首先解析出importingClass,使得bean能感知到importingClass

3.  CommonAnnotationBeanPostProcessor 用來執行前面緩存的@PostConstruct方法
CommonAnnotationBeanPostProcessor會實際調用InitDestroyAnnotationBeanPostProcessor的postProcessBeforeInitialization方法執行

 

第八個方法:一切都做了之後,對創建好的bean對象進行處理

在initializationBean中調用的是BeanPostProcess的postProcessAfterInitialization方法

在我所見至中只有aop的 AbstractAutoProxyCreator實現了這個方法,這裏就是做aop動態代理的地方

具體的

 

 

第九個 是註冊銷燬方法時,找到在第三步緩存的方法並返回,這個感覺不咋重要,我也沒認真看

 

new DisposableBeanAdapter() 構造方法中的最後一行

 

點進去

其實就是第三次緩存在InitDestroyAnnotationBeanPostProcessor的@PreDestroy方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章