瞭解了BeanDefinition
以及生命週期的大概概念以後,咱們班能夠試着看一下源碼!咱們上一章也說到,BeanFactoryPostProcessors
的執行時機是:在掃描完成以後,實例化以前! 那麼咱們看一下Spring是如何去回調BeanFactoryPostProcessors
的呢?java
org.springframework.context.support.AbstractApplicationContext#refresh
org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
invokeBeanFactoryPostProcessors就是掃描項目轉換成BeanDefinition 而後回調BeanFactoryPostProcessors的地方!咱們看源碼也是從這裏開始看!
複製代碼
我這裏會分段截取代碼進行講解,文章末尾會複製整段代碼:程序員
進入到這個方法以後,spring
BeanDefinitionRegistry
,這個判斷99%都會返回爲true,爲何呢?由於除非進行了很深度的擴展Spring,本身繼承整個工廠的頂級接口AliasRegistry
去實現一個徹底由本身實現的工廠,這個判斷纔會被跳過!這個對於咱們現階段來講,不用太過深究,咱們如今就先認定一件事,咱們使用的beanFactory工廠必定是 BeanDefinitionRegistry
類型的,這個判斷也必定會進來;BeanDefinitionRegistryPostProcessor
,爲何要存放他呢?由於他是BeanFactoryPostProcessor
的子類,在整個執行調用過程當中,咱們會先執行BeanDefinitionRegistryPostProcessor
類型的後置處理器,在執行BeanFactoryPostProcessor
類型的,可是由於是子類和父類的關係,爲了不後面重複的獲取,就索性吧BeanDefinitionRegistryPostProcessor
存儲起來,等待BeanDefinitionRegistryPostProcessor
的方法執行完畢以後,就直接執行他父類的方法,這也可以從側面證實BeanDefinitionRegistryPostProcessor
的postProcessBeanFactory
方法是優先於BeanFactoryPostProcessor
的postProcessBeanFactory
方法先執行的!固然這一點我會在後面用代碼進行驗證!這個循環是爲了循環程序員本身手動添加的後置處理器(不用太過深究,後面我會用代碼說明),若是是BeanDefinitionRegistryPostProcessor
的就先調用了,若是是BeanFactoryPostProcessor
類型的,就先放到regularPostProcessors
集合中,等待BeanDefinitionRegistryPostProcessor
執行完畢後,在進行BeanFactoryPostProcessor
的調用!緩存
咱們迎來了第一段比較重要的代碼,首先會先去在整個bean工廠尋找BeanDefinitionRegistryPostProcessor
類型的而且實現了類PriorityOrdered
的類!注意此時沒有任何人向beanFactory中放置該類型的類,他只有一個實現,就是Spring在開天闢地的時候初始化的幾個BeanDefinition
,其中有一個符合條件markdown
他就是ConfigurationClassPostProcessor
,這個類是Spring初始化的時候就放置到容器裏面的,他作的事情很很簡單,就是解析Spring配置類,而後掃描項目,將項目內符合條件的類,好比@Server、@Bean
之流加了註解的類,轉換成BeanDefinition
,而後存放到容器,請注意一點,此時通過ConfigurationClassPostProcessor
的執行以後,咱們Spring容器中有值了,有了咱們配置的全部的應該被Spring管理的類!此時再去尋找就會尋找咱們本身定義的一些後置處理器了!post
這一段代碼基本和上面的代碼同樣,惟一不一樣的就是本次尋找的是實現了Ordered
了的接口,由於上面ConfigurationClassPostProcessor
的執行,此時容器內部就又了咱們本身定義的類信息,因此若是咱們有一個類實現了BeanDefinitionRegistryPostProcessor且實現了Ordered接口,那麼此時就可以被執行了!學習
通過上面兩個實現了PriorityOrdered
、Ordered
接口兩種BeanDefinitionRegistryPostProcessor
以後,優先級別最高的已經執行完畢了,後續只須要去執行剩餘的BeanDefinitionRegistryPostProcessor
就能夠了,可是有些讀者可能會很疑惑,上面兩種調用的都是一個循環就完事了,可是爲何這裏須要一個死循環呢?spa
由於,BeanDefinitionRegistryPostProcessor
是一個接口,在回調他的方法的時候,裏面的方法可能又註冊了一些BeanDefinition
,這些BeanDefinition
也是BeanDefinitionRegistryPostProcessor
類型的,舉個例子就像俄羅斯套娃同樣,每個裏面都會進行一些註冊,誰也不知道會進行套多少層,故而要進行一個死循環,只要有,就一直遍歷尋找,直到執行完爲止!相似於下圖這樣:debug
BeanDefinitionRegistryPostProcessor
的父類方法,也就是BeanFactoryPostProcessor
的回到方法,由於BeanDefinitionRegistryPostProcessor
是BeanFactoryPostProcessor
類型的,爲了不重複查詢就實現執行了,他的優先級高於普通的BeanFactoryPostProcessor
!BeanFactoryPostProcessor
!後面說!這個代碼邏輯不難看懂code
BeanFactoryPostProcessor
類PriorityOrdered
的集合、實現了Ordered
的集合、剩餘的BeanFactoryPostProcessor
集合BeanFactoryPostProcessor
類processedBeans
集合已經存在,也就是被BeanDefinitionRegistryPostProcessor
處理過的直接跳過,避免重複執行!PriorityOrdered
接口,直接getBean()
提早實例化後,加入到對應的集合,注意此時已經進行實例化!Ordered
接口,那麼吧他的名字放到對應的集合中,注意此時他沒有實例化!BeanFactoryPostProcessor
放到對應的集合,注意也沒有實例化!經過上述,咱們知道了一件事,只有PriorityOrdered
類型的BeanFactoryPostProcessor
被實例化了,而後放置到了集合中去!
PriorityOrdered
的集合進行排序後執行,注意,由於上面在添加到集合的時候已經經過igetBean()
實例化了,因此,此時能夠直接執行!Ordered
的beanName集合,而後經過getBean
,實例化對應的BeanFactoryPostProcessor
,放到對應的集合orderedPostProcessors
,排序後進行執行!BeanFactoryPostProcessor
,而後getBean
實例化後,直接執行!/** * 掃描項目 * 調用BeanDefinitionRegistryPostProcessor 將對應的類轉成BeanDefinition * 調用 BeanFactoryPostProcessors的回調方法 * @param beanFactory bean工廠 * @param beanFactoryPostProcessors 手動提供的後置處理器 */
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 若是有的話,首先調用BeanDefinitionRegistryPostProcessors。
Set<String> processedBeans = new HashSet<>();
//默認使用的是DefaultListableBeanFactory工廠對象 因此i這個判斷必定會進入進來
if (beanFactory instanceof BeanDefinitionRegistry) {
//事實上就是Bean工廠
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//存放程序員本身手動提供給Spring的後置處理器
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//存放執行該過程當中尋找到的 BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
//循環遍歷bean工廠後處理器 可是這個的debug的對象確實爲Null不知道爲何 事實上它並不會進入到這裏
//這個是掃描用戶本身手動添加的一些BeanFactoryPostProcessors
//事實上 咱們不多會對這裏進行更改,只有在對接或者開發第三方組件的時候可能會手動的設置一個後置處理器
//正常狀況下極少可以使用到這種狀況
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//這個判斷就是爲了保證spring本身的掃描處理器先執行 由於此時spring尚未完成掃描
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
//本身定義的內助處理器
regularPostProcessors.add(postProcessor);
}
}
// 不要在這裏初始化FactoryBeans:咱們須要保留全部常規bean
// 未初始化,讓Bean工廠後處理器對其應用!
// 在實現的BeanDefinitionRegistryPostProcessor之間分開
// PriorityOrdered,Ordered和其餘。
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 首先,調用實現PriorityOrdered(排序接口)的BeanDefinitionRegistryPostProcessors。 這是獲取內置bean工廠後置處理器的beanName
//查出全部實現了BeanDefinitionRegistryPostProcessor接口的bean名稱
//調用了一次BeanDefinitionRegistryPostProcessor子類 PriorityOrdered
//獲取 BeanDefinitionRegistryPostProcessor 的子類 事實上 這裏只有一個叫作 ConfigurationClassPostProcessor 他實現了 PriorityOrdered接口
//BeanFactoryPostProcessor 也就是 ConfigurationClassPostProcessor 會被添加到容器裏面
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//判斷當前這個類是否是實現了PriorityOrdered接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//getBean會提早走生命週期
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//將這個已經處理過的添加到集合裏面
//爲何要天機哀悼集合裏面呢?由於自己他就屬於 BeanDefinitionRegistryPostProcessor 是 BeanFactoryPostProcessor的子類
//那麼確定 在執行BeanFactoryPostProcessor的回調的時候,他還會再次的被獲取執行
//索性 Spring爲了節省效率,避免這部分 BeanDefinitionRegistryPostProcessor類被重複 獲取,就在徹底調用了BeanDefinitionRegistryPostProcessor類以後
//將這一部分的接口直接給執行了也就是BeanDefinitionRegistryPostProcessor的BeanFactoryPostProcessor的回調方法是優先於直接實現BeanFactoryPostProcessor方法的
//既然在執行BeanFactoryPostProcessor以前就執行了對應的方法回調,那麼確定,執行BeanFactoryPostProcessor的時候要把以前已經執行過的過濾掉
//故而會將BeanDefinitionRegistryPostProcessor存儲起來,後續執行BeanFactoryPostProcessor會跳過集合裏面的類
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
//見該處理器添加到對應的已註冊集合裏面 方面後面直接回調他們的父類方法也就是 BeanFactoryPostProcessors方法
registryProcessors.addAll(currentRegistryProcessors);
//調用Bean定義註冊表後處理器 這裏是真正的讀取類的bd的一個方法 ConfigurationClassPostProcessor 第一次調用beanFactory 後置處理器
//這裏調用ConfigurationClassPostProcessor後置處理器會註冊一個後置處理器,下面進行回調
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清空當前這個處理器
currentRegistryProcessors.clear();
// 接下來,調用實現Ordered的BeanDefinitionRegistryPostProcessors。 Ordered
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//判斷當前這個類是否是實現了Ordered接口
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
//getBean會提早走生命週期
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
//見該處理器添加到對應的已註冊集合裏面 方面後面直接回調他們的父類方法也就是 BeanFactoryPostProcessors方法
registryProcessors.addAll(currentRegistryProcessors);
//調用當前的BeanDefinitionRegistryPostProcessor 回調方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清空當前這個處理器
currentRegistryProcessors.clear();
// 最後,調用全部其餘BeanDefinitionRegistryPostProcessor,直到沒有其餘的出現。
boolean reiterate = true;
//這裏爲何是死循環呢?
//由於 BeanDefinitionRegistryPostProcessor 自己進行回調的時候會手動註冊一些特殊的類,例如再次註冊一個BeanDefinitionRegistryPostProcessor
//類,可能手動註冊的類裏面還有,像套娃同樣,故而須要進行不斷的循環迭代獲取,從而達到遍歷所有的 BeanDefinitionRegistryPostProcessor的目的
while (reiterate) {
reiterate = false;
//獲取全部的BeanDefinitionRegistryPostProcessor接口的實現類
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//遍歷這些BeanDefinitionRegistryPostProcessor類
for (String ppName : postProcessorNames) {
//若是它不存在與這個集合裏面,證實沒有被上面處理過,就不會被跳過,這裏主要是解決重複執行的狀況
if (!processedBeans.contains(ppName)) {
//添加到對應的當前處理器集合裏面
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//添加到已處理集合裏面
processedBeans.add(ppName);
//將掃描標識爲true 準備下次執行
reiterate = true;
}
}
//排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//註冊到註冊集合裏面,便於後修直接回調父類
registryProcessors.addAll(currentRegistryProcessors);
//開始執行這些方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清空本次執行的處理集合
currentRegistryProcessors.clear();
}
// 如今,調用到目前爲止已處理的全部處理器的postProcessBeanFactory回調。
//BeanDefinitionRegistryPostProcessor 是 BeanFactoryPostProcessor
//目的就是爲了不重複獲取
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//常規的 普通的工廠後置處理器
//程序員手動提供給Spring的BeanFactory beanFactory.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor())
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
// 調用在上下文實例中註冊的工廠處理器。
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 不要在這裏初始化FactoryBeans:咱們須要保留全部常規bean
// 未初始化,讓Bean工廠後處理器對其應用!
//這裏是真正獲取容器內部全部的beanFactory的後置處理器
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
//上面是否已經被執行過了,執行過的直接跳過
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
//添加 實現了PriorityOrdered的BeanFactoryPostProcessors
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
//添加 實現了Ordered的BeanFactoryPostProcessors
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
//添加剩餘的
nonOrderedPostProcessorNames.add(ppName);
}
}
// 首先,調用實現PriorityOrdered的BeanFactoryPostProcessors。
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//首先回調實現了PriorityOrdered的BeanFactoryPostProcessors
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 接下來,調用實現Ordered的BeanFactoryPostProcessors。
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
//getBean能夠進行提早實例化進入生命週期
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
// 接下來,調用實現Ordered的BeanFactoryPostProcessors。
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
//最後,調用全部其餘BeanFactoryPostProcessors。
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
//getBean能夠進行提早實例化進入生命週期
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
//這裏執行的自定義的bean工廠的後置處理器
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// 清除緩存的合併bean定義,由於後處理器可能具備修改了原始元數據,例如替換值中的佔位符...
beanFactory.clearMetadataCache();
}
複製代碼
才疏學淺,若是文章中理解有誤,歡迎大佬們私聊指正!歡迎關注做者的公衆號,一塊兒進步,一塊兒學習!