javascript
Spring5源码 - 05 invokeBeanFactoryPostProcessors 源码解读_2
文章目錄
- Pre
- 源碼解讀
- 總體流程
- 源碼分析
- 細節(jié)解析
- 【初始化對應的集合 & 遍歷用戶自己手動添加的后置處理器】
- 【調用實現(xiàn)了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor】
- 【調用實現(xiàn)了Ordered接口的BeanDefinitionRegistryPostProcessor】
- 【調用剩余的BeanDefinitionRegistryPostProcessor】
- 【開始調用BeanDefinitionRegistryPostProcessor的父類方法】
- 【尋找BeanFactoryPostProcessor】
- 【執(zhí)行BeanFactoryPostProcessor】
- 小結
Pre
接上文 Spring5源碼 - 04 invokeBeanFactoryPostProcessors 源碼解讀_1
源碼解讀
總體流程
我們知道了 BeanFactoryPostProcessors的執(zhí)行時機是:在掃描完成之后,Bean實例化之前 , 那Spring是如何去回調BeanFactoryPostProcessors的呢?
invokeBeanFactoryPostProcessors就是掃描項目將掃描到的類轉換成BeanDefinition 然后回調BeanFactoryPostProcessors的地方,故這個方法很重要 。
源碼分析
/****調用bean工廠的后置處理器* 1)BeanDefinitionRegistryPostProcessor(先被執(zhí)行)* 所有的bean定義信息將要被加載到容器中,Bean實例還沒有被初始化* 2)BeanFactoryPostProcessor(后執(zhí)行)* 所有的Bean定義信息已經(jīng)加載到容器中,但是Bean實例還沒有被初始化.* 該方法的作用就是用于ioc容器加載bean定義前后進行處理* BeanDefinitionRegistryPostProcessor是bean定義解析前調用* 1)實現(xiàn)了PriorityOrdered接口的* 2)實現(xiàn)了Ordered接口的* 3)沒有實現(xiàn)任何的優(yōu)先級接口的* 4)因為BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor接口的子接口,實現(xiàn)BeanFactoryPostProcessor的方法* BeanFactoryPostProcessor是bean定義解析后調用* 1)實現(xiàn)了PriorityOrdered接口的* 2)實現(xiàn)了Ordered接口的* 3)沒有實現(xiàn)任何的優(yōu)先級接口的* @author Juergen Hoeller* @since 4.0*/ final class PostProcessorRegistrationDelegate {public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {//第一步:首先調用BeanDefinitionRegistryPostProcessor的后置處理器Set<String> processedBeans = new HashSet<>();//判斷我們的beanFacotry實現(xiàn)了BeanDefinitionRegistryif (beanFactory instanceof BeanDefinitionRegistry) {//強行把我們的bean工廠轉為BeanDefinitionRegistryBeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;//保存BeanFactoryPostProcessor類型的后置List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();//保存BeanDefinitionRegistryPostProcessor類型的后置處理器List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();//循環(huán)我們傳遞進來的beanFactoryPostProcessorsfor (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {//判斷我們的后置處理器是不是BeanDefinitionRegistryPostProcessorif (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {//進行強制轉化BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;//調用他作為BeanDefinitionRegistryPostProcessor的處理器的后置方法registryProcessor.postProcessBeanDefinitionRegistry(registry);//添加到我們用于保存的BeanDefinitionRegistryPostProcessor的集合中registryProcessors.add(registryProcessor);}else {//若沒有實現(xiàn)BeanDefinitionRegistryPostProcessor 接口,那么他就是BeanFactoryPostProcessor//把當前的后置處理器加入到regularPostProcessors中regularPostProcessors.add(postProcessor);}}//定義一個集合用戶保存當前準備創(chuàng)建的BeanDefinitionRegistryPostProcessorList<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();//第一步:去容器中獲取BeanDefinitionRegistryPostProcessor的bean的處理器名稱String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);//循環(huán)上一步獲取的BeanDefinitionRegistryPostProcessor的類型名稱for (String ppName : postProcessorNames) {//判斷是否實現(xiàn)了PriorityOrdered接口的if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//顯示的調用getBean()的方式獲取出該對象然后加入到currentRegistryProcessors集合中去currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));//同時也加入到processedBeans集合中去processedBeans.add(ppName);}}//對currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor進行排序sortPostProcessors(currentRegistryProcessors, beanFactory);//把他加入到用于保存到registryProcessors中registryProcessors.addAll(currentRegistryProcessors);/*** 在這里典型的BeanDefinitionRegistryPostProcessor就是ConfigurationClassPostProcessor* 用于進行bean定義的加載 比如我們的包掃描,@import 等等。。。。。。。。。*/invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);//調用完之后,馬上clea掉currentRegistryProcessors.clear();//去容器中獲取BeanDefinitionRegistryPostProcessor的bean的處理器名稱postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);//循環(huán)上一步獲取的BeanDefinitionRegistryPostProcessor的類型名稱for (String ppName : postProcessorNames) {//表示沒有被處理過,且實現(xiàn)了Ordered接口的if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {//顯示的調用getBean()的方式獲取出該對象然后加入到currentRegistryProcessors集合中去currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));//同時也加入到processedBeans集合中去processedBeans.add(ppName);}}//對currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor進行排序sortPostProcessors(currentRegistryProcessors, beanFactory);//把他加入到用于保存到registryProcessors中registryProcessors.addAll(currentRegistryProcessors);//調用他的后置處理方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);//調用完之后,馬上clea掉currentRegistryProcessors.clear();//調用沒有實現(xiàn)任何優(yōu)先級接口的BeanDefinitionRegistryPostProcessor//定義一個重復處理的開關變量 默認值為trueboolean reiterate = true;//第一次就可以進來while (reiterate) {//進入循環(huán)馬上把開關變量給改為faslereiterate = false;//去容器中獲取BeanDefinitionRegistryPostProcessor的bean的處理器名稱postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);//循環(huán)上一步獲取的BeanDefinitionRegistryPostProcessor的類型名稱for (String ppName : postProcessorNames) {//沒有被處理過的if (!processedBeans.contains(ppName)) {//顯示的調用getBean()的方式獲取出該對象然后加入到currentRegistryProcessors集合中去currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));//同時也加入到processedBeans集合中去processedBeans.add(ppName);//再次設置為truereiterate = true;}}//對currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor進行排序sortPostProcessors(currentRegistryProcessors, beanFactory);//把他加入到用于保存到registryProcessors中registryProcessors.addAll(currentRegistryProcessors);//調用他的后置處理方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);//進行clearcurrentRegistryProcessors.clear();}//調用實現(xiàn)了BeanDefinitionRegistryPostProcessor的接口 他是他也同時實現(xiàn)了BeanFactoryPostProcessor的方法invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);//調用BeanFactoryPostProcessor成品的不是通過getBean的invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else { //若當前的beanFacotory沒有實現(xiàn)了BeanDefinitionRegistry 直接調用 beanFacotoryPostProcessor接口的方法進行后置處理invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}//獲取容器中所有的 BeanFactoryPostProcessorString[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);//保存BeanFactoryPostProcessor類型實現(xiàn)了priorityOrderedList<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();//保存BeanFactoryPostProcessor類型實現(xiàn)了Ordered接口的List<String> orderedPostProcessorNames = new ArrayList<>();//保存BeanFactoryPostProcessor沒有實現(xiàn)任何優(yōu)先級接口的List<String> nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) {//processedBeans包含的話,表示在上面處理BeanDefinitionRegistryPostProcessor的時候處理過了if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}//判斷是否實現(xiàn)了PriorityOrderedelse if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}//判斷是否實現(xiàn)了Orderedelse if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}//沒有實現(xiàn)任何的優(yōu)先級接口的else {nonOrderedPostProcessorNames.add(ppName);}}// 先調用BeanFactoryPostProcessor實現(xiàn)了 PriorityOrdered接口的sortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);//再調用BeanFactoryPostProcessor實現(xiàn)了 Ordered.List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);//調用沒有實現(xiàn)任何方法接口的List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();for (String postProcessorName : nonOrderedPostProcessorNames) {nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);// Clear cached merged bean definitions since the post-processors might have// modified the original metadata, e.g. replacing placeholders in values...beanFactory.clearMetadataCache();}...... }是不是發(fā)現(xiàn) 這個方法中的 好幾個部分的代碼 很相似?
細節(jié)解析
我們說 這個BeanFactoryPostProcessors 大部分情況下是沒有值的,那什么場景下會有有值呢?
舉個例子
addBeanFactoryPostProcessor
所以
就取到值了。
那繼續(xù)分段來解讀Spring的設計思想
【初始化對應的集合 & 遍歷用戶自己手動添加的后置處理器】
來分解下代碼
第二個集合是干啥的呢? List<BeanDefinitionRegistryPostProcessor> registryProcessors 同樣的看類型 BeanDefinitionRegistryPostProcessor ,這個就是存放執(zhí)行過程中找到的BeanDefinitionRegistryPostProcessor
存放它的意圖是什么呢?
因為BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子類,在整個執(zhí)行調用過程中,我們會先執(zhí)行BeanDefinitionRegistryPostProcessor類型的后置處理器,在執(zhí)行BeanFactoryPostProcessor類型的,但是因為是子類和父類的關系,為了避免后面重復的獲取,就也把BeanDefinitionRegistryPostProcessor存儲起來,等待BeanDefinitionRegistryPostProcessor的方法執(zhí)行完畢之后,就直接執(zhí)行它父類的方法,這也能夠從側面證明BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法是優(yōu)先于BeanFactoryPostProcessor的postProcessBeanFactory方法先執(zhí)行的
【調用實現(xiàn)了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor】
這是第一個重點的Code , 首先會先去在整個bean工廠尋找BeanDefinitionRegistryPostProcessor類型的并且實現(xiàn)了類PriorityOrdered的類 .
注意此時沒有任何人向beanFactory中放置該類型的類,只有一個實現(xiàn),就是Spring在開天辟地的時候初始化的幾個BeanDefinition,其中有一個符合條件
ConfigurationClassPostProcessor,這個類是Spring初始化的時候就放置到容器里面的,主要作用就是解析Spring配置類,然后掃描項目,將項目內符合條件的類,比如@Server、@Bean之流加了注解的類,轉換成BeanDefinition,然后存放到容器,請注意一點,此時經(jīng)過ConfigurationClassPostProcessor的執(zhí)行之后 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());,Spring容器中就有值了,有了我們配置的所有的應該被Spring管理的類!此時再去尋找就會尋找我們自己定義的一些后置處理器了!
【調用實現(xiàn)了Ordered接口的BeanDefinitionRegistryPostProcessor】
我們看下找到了啥
繼續(xù) 看是否符合條件
這里不會處理,因為已經(jīng)處理過了 !processedBeans.contains(ppName)
這段代碼的含義就是: 基本和上面的代碼一樣,唯一不同的就是本次尋找的是實現(xiàn)了Ordered了的接口,因為上面ConfigurationClassPostProcessor的執(zhí)行,此時容器內部就有了我們自己定義的類信息,所以如果我們有一個類實現(xiàn)了BeanDefinitionRegistryPostProcessor且實現(xiàn)了Ordered接口,那么此時就能夠被執(zhí)行了 。
【調用剩余的BeanDefinitionRegistryPostProcessor】
經(jīng)過上面兩個實現(xiàn)了PriorityOrdered、Ordered接口兩種BeanDefinitionRegistryPostProcessor之后,優(yōu)先級別最高的已經(jīng)執(zhí)行完畢了,后續(xù)只需要去執(zhí)行剩余的BeanDefinitionRegistryPostProcessor就可以了 .
這里為什么有個循環(huán)呢?
因為,BeanDefinitionRegistryPostProcessor是一個接口,在回調他的方法的時候,里面的方法可能又注冊了一些BeanDefinition,這些BeanDefinition也是BeanDefinitionRegistryPostProcessor類型的。
舉個例子就像俄羅斯套娃一樣,每一個里面都會進行一些注冊,不知道會套多少層,所以要進行一個死循環(huán),只要有,就一直遍歷尋找,直到執(zhí)行完為止!類似于下圖這樣:
【開始調用BeanDefinitionRegistryPostProcessor的父類方法】
第一行 :執(zhí)行BeanDefinitionRegistryPostProcessor的父類方法,也就是BeanFactoryPostProcessor的接口方法,因為BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor類型的,為了避免重復查詢就事先執(zhí)行了,他的優(yōu)先級高于普通的BeanFactoryPostProcessor
第二行: 執(zhí)行用戶手動添加的BeanFactoryPostProcessor
【尋找BeanFactoryPostProcessor】
看下找到了誰?
判斷是否有處理
主要流程
將普通的BeanFactoryPostProcessor放到對應的集合,注意也沒有實例化
通過上述, 只有PriorityOrdered類型的BeanFactoryPostProcessor被實例化了,然后放置到了集合中去!
【執(zhí)行BeanFactoryPostProcessor】
小結
至此invokeBeanFactoryPostProcessors 所有的Code就分析了 ,方法執(zhí)行完以后就完成了對所有符合條件的對象的掃描 ,如果有符合條件的,會通過getBean方法提前實例化。
總結
以上是生活随笔為你收集整理的Spring5源码 - 05 invokeBeanFactoryPostProcessors 源码解读_2的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring5源码 - 04 invok
- 下一篇: Spring5源码 - 06 Sprin