spring的后置處理器有兩類疆柔,bean后置處理器,bf(BeanFactory)后置處理器。bean后置處理器作用于bean的生命周期,bf的后置處理器作用于bean工廠的生命周期。
BF后置處理器
Spring是一個bean依賴注入容器,容器是BF,它的上級對象是applicationContxt,applicationContxt在容器功能上附加了一下新的功能卦洽。我們使用spring時,用的都是applicationConext的實現(xiàn)類斜棚。
我們在初始化這些applicationConext時阀蒂,最終調(diào)用的都是org.springframework.context.support.AbstractApplicationContext#refresh方法用于容器的初始化。這個方法是一個模板方法弟蚀,規(guī)定了容器實例化的步驟蚤霞。其中BF初始化完成后,會調(diào)用BF的后置處理器對BF進行后置處理义钉。而后置處理器的調(diào)用是在org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors這個方法中進行的昧绣。
BF的后置處理器有兩種,BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor捶闸。BF后置處理器和BD(BeanDefinition)后置處理器夜畴。BD后置處理器是BF后置處理器的子接口。下面是BF后置處理器的api截圖删壮。
invokeBeanFactoryPostProcessors方法內(nèi)贪绘,調(diào)用后置處理器的步驟如下:
- 通過ac(applicationContext)的addBeanFactoryPostProcessor方法加入的BD后置處理器,按照加入順序調(diào)用央碟。
- ac中類型為bd后置處理器的税灌,擁有PriorityOrdered接口的BD后置處理器。
- ac中類型為bd后置處理器的,擁有Ordered接口的BD后置處理器垄琐。
- ac中類型為bd后置處理器的,PriorityOrdered和Ordered接口都沒實現(xiàn)的BeanDefinitionRegistryPostProcessor
- ac中類型為bf后置處理器的经柴,擁有PriorityOrdered接口的BF后置處理器狸窘。
- ac中類型為bf后置處理器的,擁有Ordered接口的BF后置處理器坯认。
- ac中類型為bf后置處理器的翻擒,PriorityOrdered和Ordered接口都沒實現(xiàn)的BeanFactoryPostProcessor
在AnnotationConfigApplicationContext上下文中,會有一個關(guān)鍵的BD后置處理器:ConfigurationClassPostProcessor牛哺。它是用來掃描所有交給spring管理的注解類的陋气。將其解析為BD實例放到AC中去。
Bean后置處理器
spring管理的是bean引润,所以bean的實例化是一個重要的過程巩趁。spring是通過org.springframework.beans.factory.support.AbstractBeanFactory#getBean方法實例化并初始化Bean。實例化Bean的過程中淳附,可以通過bean的后置處理器插手Bean的實例化過程议慰。
Bean的實例化過程如下:
- 解析BD
- 確定構(gòu)造方法
- 用構(gòu)造方法實例化(構(gòu)造方法依賴不能進行循環(huán)依賴)
- 屬性注入
- 初始化
在這個過程中,spring內(nèi)設(shè)了8個bean的后置處理器調(diào)用點奴曙,用來進行擴展别凹。
Bean后置處理器有五種:
- BeanPostProcessor:基本后置處理器洽糟,有兩個方法,分別在Bean初始化前后調(diào)用
- postProcessBeforeInitialization在初始化之前調(diào)用
- postProcessAfterInitialization在初始化之后調(diào)用
- DestructionAwareBeanPostProcessor在bean被摧毀的時候調(diào)用
- InstantiationAwareBeanPostProcessor:有三個方法坤溃,
- postProcessBeforeInstantiation在最開始調(diào)用,如果返回Bean實例不為空薪介,直接調(diào)用BeanPostProcessor的postProcessAfterInitialization方法沉御,返回該bean昭灵,不在進行其他動作。
- postProcessAfterInstantiation判斷是否需要進行屬性填充
- postProcessPropertyValues烂完,進行屬性填充前试疙,處理bean的PropertyValues。用于屬性填充
- MergedBeanDefinitionPostProcessor抠蚣,只有一個方法,postProcessMergedBeanDefinition怀跛,在實例化之前,對BD進行后置處理忠蝗。
- SmartInstantiationAwareBeanPostProcessor漓拾,有三個方法
- predictBeanType,預(yù)測InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法返回的類型骇两。
- determineCandidateConstructors低千,確定該bd的構(gòu)造函數(shù),找不到用默認的構(gòu)造函數(shù)
- getEarlyBeanReference示血,在需要獲取earlyBean時矾芙,在返回earlyBean前對earlyBean進行后置處理。
Bean后置處理器的API截圖: