spring 5.0.x源碼學(xué)習(xí)系列五: AnnotationConfigApplicationContext類refresh方法之invokeBeanFactoryPostProcessor(一)

前言

一、refresh源碼黑箱理論

  • 在此篇章中,咱們先把源碼中每個方法的執(zhí)行流程先列出來, 再根據(jù)每一個具體的方法進(jìn)行解析
  • 源碼
    
        @Override
        public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                // Prepare this context for refreshing.
                prepareRefresh();
    
                // 獲取spring bean工廠
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
                // Prepare the bean factory for use in this context.
                // 這個方法執(zhí)行完成, spring的bean單例容器中會存在三個bean,
                // 分別是systemEnvironment, environment, systemProperties
                // 同時會添加ApplicationContextAwareProcessor的后置處理器, 這個處理器沒有走
                // spring的bean初始化, 是在內(nèi)部直接new出來的, 該處理器是用來處理實現(xiàn)了
                // ApplicationContextAware接口的bean, 調(diào)用重寫的set方法, 所以可以利用
                // 這種方法獲取spring的上下文對象
                prepareBeanFactory(beanFactory);
    
                try {
                    // 該方法沒有做任何事, 內(nèi)部無任何邏輯
                    postProcessBeanFactory(beanFactory);
    
                    // 調(diào)用后置處理器, 此方法太重要了, 在后續(xù)的源碼解讀系列中會解析它
                    // 先大致總結(jié)下它做了什么事
                    // 1. 處理手動添加的BeanFactoryPostProcessor
                    //   1.1 調(diào)用手動添加的BeanDefinitionRegistryPostProcessor, 并添加到存儲它的集合中,
                    //       該集合名字為: registryProcessors
                    //   1.2 存儲手動添加的BeanFactoryPostProcessor,
                    //       該集合名字為: regularPostProcessors
                    //   注意: 上面這個步驟是if else邏輯, 存了一個另外一個就不會存了
                    // 2. 執(zhí)行BeanDefinitionRegistryPostProcessor類型且實現(xiàn)了PriorityOrdered接
                    //    口的后置處理器. 默認(rèn)執(zhí)行spring內(nèi)置BeanDefinitionRegistryPostProcessor
                    //    后置處理器(ConfigurationClassPostProcessor), 這個后置處理器執(zhí)行完之后,
                    //    所有能被掃描出來的bean都以BeanDefinition的方式注冊到bean工廠了
                    // 3. 執(zhí)行BeanDefinitionRegistryPostProcessor類型且實現(xiàn)了
                    //    Ordered接口的后置處理器
                    // 4. 執(zhí)行以@Component方式添加的BeanDefinitionRegistryPostProcessor類型沒實現(xiàn)
                    //    Ordered和PriorityOrdered接口的后置處理器
                    // 5. 執(zhí)行regularPostProcessors和registryProcessors數(shù)據(jù)結(jié)構(gòu)中
                    //    BeanFactoryPostProcessor類型的后置處理器(在此處執(zhí)行
                    //    ConfigurationClassPostProcessor類的postProcessBeanFactory方法, 主要是
                    //    為全配置類生成了cglib代理類的Class對象, 并修改它的beanDefinition信息為代
                    //    理類的信息
                    // 6. 執(zhí)行以@Component形式添加并實現(xiàn)了PriorityOrdered接口的BeanFactoryPost
                    //    Processor后置處理器
                    // 7. 執(zhí)行以@Component形式添加并實現(xiàn)了Ordered接口的BeanFactoryPost
                    //    Processor后置處理器
                    // 8. 執(zhí)行以@Component形式添加并未實現(xiàn)PriorityOrdered和Ordered接口的Bean
                    //    FactoryPostProcessor后置處理器
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // 注冊spring bean工廠的BeanPostProcessor
                    // 其中包括spring內(nèi)置的、掃描出來的(eg: 使用ImportBeanDefinitionRegistrar, AOP的實現(xiàn)方式)倒彰、
                    // 自己手動添加的(手動添加BeanDefinitionRegistryPostProcessor,
                    // 并在其中注冊一個BeanPostProcessor的bean)
                    //
                    // 默認(rèn)情況下, spring內(nèi)置的3個BeanPostProcessor分別為:
                    //   org.springframework.context.annotation.internalAutowiredAnnotationProcessor   => 處理@Autowired注解的
                    //   org.springframework.context.annotation.internalRequiredAnnotationProcessor  => 處理@Required注解的
                    //   org.springframework.context.annotation.internalCommonAnnotationProcessor  => 處理Common注解的后置處理器
                    // 以及各種實現(xiàn)了PriorityOrdered接口、Ordered接口的BeanPostProcessor處理
                    // 最主要的就是把這些bean通過spring bean工廠創(chuàng)建出來, 并添加到一個存放BeanPostProcessor的list中, 再利用廣播
                    // 機(jī)制調(diào)用
                    // 我覺得這里用list而不用set的原因有兩個
                    // 1. list是有序的, 因為有些BeanPostProcessor會實現(xiàn)PriorityOrdered接口榨为、Ordered接口, 所以要按照一定的順序執(zhí)行
                    // 2. 廣播機(jī)制時要遍歷集合, list遍歷速度快一些
                    registerBeanPostProcessors(beanFactory);
    
                    // Initialize message source for this context.
                    // 國際化
                    initMessageSource();
    
                    // Initialize event multicaster for this context.
                    // 初始化spring事件驅(qū)動模型的執(zhí)行者
                    initApplicationEventMulticaster();
    
                    // 該方法沒有做任何事, 內(nèi)部無任何邏輯
                    onRefresh();
    
                    // 注冊自己手動添加的監(jiān)聽器和spring掃描出來的監(jiān)聽器
                    // 手動添加的監(jiān)聽器: 調(diào)用spring上下文的addApplicationListener方法, eg: AnnotationConfigApplicationContext上下文的方法
                    // spring掃描出來的監(jiān)聽器: 有@Component注解標(biāo)識的監(jiān)聽器
                    // 這里有人會問: 萬一我一個監(jiān)聽器同時加了@Component注解也手動調(diào)用了addApplicationListener添加呢里初?
                    // 沒關(guān)系, 那就執(zhí)行兩次唄, 因為spring處理手動添加的和掃描出來的監(jiān)聽器是不一樣的, 手動添加的是一個java 對象, 而spring掃描出來
                    // 的監(jiān)聽器是一個bean, 所以這兩個監(jiān)聽器是同一類型的不同對象
                    // 但要注意的是, 手動添加的監(jiān)聽器是一個java object, 而spring掃描出來的是一個bean
                    registerListeners();
    
                    // 開始創(chuàng)建非抽象啃勉、非原型、非懶加載的bean 以及處理bean的自動裝配
                    finishBeanFactoryInitialization(beanFactory);
    
                    // 完成刷新, 發(fā)布相應(yīng)的事件
                    finishRefresh();
                }
    
                catch (BeansException ex) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Exception encountered during context initialization - " +
                                "cancelling refresh attempt: " + ex);
                    }
    
                    // Destroy already created singletons to avoid dangling resources.
                    destroyBeans();
    
                    // Reset 'active' flag.
                    cancelRefresh(ex);
    
                    // Propagate exception to caller.
                    throw ex;
                }
    
                finally {
                    // Reset common introspection caches in Spring's core, since we
                    // might not ever need metadata for singleton beans anymore...
                    resetCommonCaches();
                }
            }
        }
        
    
  • 總結(jié)
    1. 由源碼中的注釋可知: refresh方法主要做的就是填充spring的整個bean環(huán)境(之前的spring環(huán)境都是空殼), 包括掃描bean双妨,初始化非抽象淮阐、單例、非懶加載的bean, 以及初始化spring事件驅(qū)動模型刁品。
    2. 這里提供下spring 上下文環(huán)境的圖, 方便理解大致結(jié)構(gòu)
      spring上下文環(huán)境

二泣特、本篇博客的主角: invokeBeanFactoryPostProcessor方法

  • 流程圖


    在這里插入圖片描述
  • 源碼注釋
        public static void invokeBeanFactoryPostProcessors(
                   ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
       
           // Invoke BeanDefinitionRegistryPostProcessors first, if any.
           Set<String> processedBeans = new HashSet<>();
    
           // 傳入的bean工廠DefaultListableBeanFactory也是一個BeanDefinitionRegistry, 它實現(xiàn)了這個接口
           if (beanFactory instanceof BeanDefinitionRegistry) {
               BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    
               // 用來存儲手動添加BeanFactoryPostProcessor的處理器,
               // eg: context.addBeanFactoryPostProcessor(new MyBeanDefinitionRegistryPostProcessor());
               // 其中context是AnnotationConfigApplicationContext對象, 但是它只是執(zhí)行到了父類AbstractApplicationContext的方法
               List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
    
               // 用來存儲手動添加BeanDefinitionRegistryPostProcessor的處理器, 也是執(zhí)行上述注釋中說的方法
               // 因為BeanFactoryPostProcessor有一個子類叫BeanDefinitionRegistryPostProcessor
               // regularPostProcessors和registryProcessors這兩個list只是為了存儲手動添加的BeanFactoryPostProcessor
               List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    
               for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                   if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                       BeanDefinitionRegistryPostProcessor registryProcessor =
                               (BeanDefinitionRegistryPostProcessor) postProcessor;
                       // 對于手動添加的BeanDefinitionRegistryPostProcessor會在這里第一次被調(diào)用, 所以這里是后置處理器第一次被調(diào)用的地方
                       registryProcessor.postProcessBeanDefinitionRegistry(registry);
                       // 存儲手動添加的BeanDefinitionRegistryPostProcessor, 后續(xù)會用到
                       registryProcessors.add(registryProcessor);
                   }
                   else {
                       // 存儲手動添加的BeanFactoryPostProcessor, 后續(xù)會用到
                       regularPostProcessors.add(postProcessor);
                   }
               }
    
               // 這個list是用來存儲spring內(nèi)置的BeanFactoryPostProcessor
               List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    
               // 這里是調(diào)用實現(xiàn)了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor后置處理器
               // 這里只是獲取, 調(diào)用是在下面的invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);完成的
               String[] postProcessorNames =
                       beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
               for (String ppName : postProcessorNames) {
                   if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                       currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                       processedBeans.add(ppName);
                   }
               }
               sortPostProcessors(currentRegistryProcessors, beanFactory);
               registryProcessors.addAll(currentRegistryProcessors);
               // 這里首先調(diào)用的類是spring內(nèi)置beanName叫org.springframework.context.annotation.internalConfigurationAnnotationProcessor,
               // 類名叫ConfigurationClassPostProcessor的bean
               // 因為在spring內(nèi)置的6個bean中只有它是實現(xiàn)了BeanDefinitionRegistryPostProcessor接口
               // 所以ConfigurationClassPostProcessor類這一次被調(diào)用的主要目的是:
               // 1. 為bean工廠生成factoryId并記錄起來
               // 2. 循環(huán)解析傳入的配置類(即傳入register方法中的幾個Class類對應(yīng)的類)
               //  2.1 根據(jù)類獲取他們的BeanDefinition, 來判斷BeanDefinition是否為AnnotatedBeanDefinition類型(因為目前是考慮java config模式, 所以只考慮這種類型)
               //  2.2 判斷傳入類是否加了@Configuration注解或者(@Component和@ComponentScan和@Import和ImportResource注解)或者內(nèi)部是否有方法添加了@Bean注解并解析他們
               invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
               currentRegistryProcessors.clear();
    
               // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
               postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
               for (String ppName : postProcessorNames) {
                   if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                       currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                       processedBeans.add(ppName);
                   }
               }
               sortPostProcessors(currentRegistryProcessors, beanFactory);
               registryProcessors.addAll(currentRegistryProcessors);
               invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
               currentRegistryProcessors.clear();
    
               // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
               boolean reiterate = true;
               while (reiterate) {
                   reiterate = false;
                   postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                   for (String ppName : postProcessorNames) {
                       if (!processedBeans.contains(ppName)) {
                           currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                           processedBeans.add(ppName);
                           reiterate = true;
                       }
                   }
                   sortPostProcessors(currentRegistryProcessors, beanFactory);
                   registryProcessors.addAll(currentRegistryProcessors);
                   invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                   currentRegistryProcessors.clear();
               }
    
               // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
               // 這里是第一次調(diào)用手動添加到spring的BeanDefinitionRegistryPostProcessor的重寫B(tài)eanFactoryPostProcessors接口的(postProcessBeanFactory)方法
               // 因為BeanDefinitionRegistryPostProcessor是繼承BeanFactoryPostProcessor類。所以也重寫了BeanFactoryPostProcessor的方法
               // 在第一次調(diào)用時只調(diào)用了BeanDefinitionRegisterPostProcessor中的方法
               invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
               // 這里是第一次調(diào)用手動添加到spring的BeanFactoryPostProcessor
               invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
           }
    
           else {
               // Invoke factory processors registered with the context instance.
               invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
           }
    
           // Do not initialize FactoryBeans here: We need to leave all regular beans
           // uninitialized to let the bean factory post-processors apply to them!
           // 這里是調(diào)用非手動添加的BeanFactoryPostProcessor后置處理器, 即使用了@Component注解
           // 因為在上一步調(diào)用ConfigurationClassPostProcessor這種類型(BeanDefinitionRegistryBeanFactory)的后置處理器時, 對包已經(jīng)掃描成功挑随,
           // 并將掃描出來的類信息封裝成ScannedGenericBeanDefinition的BeanDefinition了, 所以根據(jù)類型找出的來的bean包括以注解的方式注冊的
           // BeanFactoryPostProcessor状您,但也包括ConfigurationClassPostProcessor, 因為它實現(xiàn)的BeanDefinitionRegistryBeanFactory接口也
           // 繼承了BeanFactoryPostProcessor接口
           String[] postProcessorNames =
                   beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
           // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
           // Ordered, and the rest.
           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
               }
               else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                   priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
               }
               else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                   orderedPostProcessorNames.add(ppName);
               }
               else {
                   nonOrderedPostProcessorNames.add(ppName);
               }
           }
    
           // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
           // 解析實現(xiàn)了PriorityOrdered接口的BeanFactoryPostProcessor并按順序執(zhí)行
           sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
           invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
           // 解析實現(xiàn)了Ordered接口的BeanFactoryPostProcessor并按順序執(zhí)行
           List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
           for (String postProcessorName : orderedPostProcessorNames) {
               orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
           }
           sortPostProcessors(orderedPostProcessors, beanFactory);
           invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
           // 調(diào)用實現(xiàn)了沒有實現(xiàn)PriorityOrdered和Ordered接口的BeanFactoryPostProcessor的后置處理器
           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();
       }
    

三、項目測試demo

3.1 項目結(jié)構(gòu)

3.1.1 結(jié)構(gòu)全景圖

  • 在這里插入圖片描述

3.1.2 各類詳情與作用

  1. 項目入口(啟動spring環(huán)境的入口)


    在這里插入圖片描述
  2. 全配置類, 定義掃描的包


    在這里插入圖片描述
  3. 手動添加的BeanDefinitionRegistryPostProcessor


    在這里插入圖片描述
  4. 手動添加的BeanFactoryPostProcessor


    在這里插入圖片描述
  5. 由spring掃描出來的BeanDefinitionRegistryPostProcessor但無實現(xiàn)Ordered和PriorityOrdered接口


    在這里插入圖片描述
  6. 由spring掃描出來的BeanDefinitionRegistryPostProcessor實現(xiàn)了Ordered接口, 且權(quán)重為1 => 權(quán)重低, 優(yōu)先執(zhí)行


    在這里插入圖片描述
  7. 由spring掃描出來的BeanDefinitionRegistryPostProcessor實現(xiàn)了Ordered接口, 且權(quán)重為2 => 權(quán)重低, 優(yōu)先執(zhí)行


    在這里插入圖片描述
  8. 由spring掃描出來的BeanDefinitionRegistryPostProcessor實現(xiàn)了PriorityOrdered接口, 且權(quán)重為1 => 權(quán)重低, 優(yōu)先執(zhí)行


    在這里插入圖片描述
  9. 由spring掃描出來的BeanDefinitionRegistryPostProcessor實現(xiàn)了PriorityOrdered接口, 且權(quán)重為2 => 權(quán)重低, 優(yōu)先執(zhí)行


    在這里插入圖片描述
  10. 由spring掃描出來的BeanFactoryPostProcessor


    在這里插入圖片描述
  11. 由spring掃描出來的BeanFactoryPostProcessor實現(xiàn)了Ordered接口, 且權(quán)重為1 => 權(quán)重越低, 越優(yōu)先執(zhí)行


    在這里插入圖片描述
  12. 由spring掃描出來的BeanFactoryPostProcessor實現(xiàn)了Ordered接口, 且權(quán)重為2 => 權(quán)重越低, 越優(yōu)先執(zhí)行


    在這里插入圖片描述
  13. 由spring掃描出來的BeanFactoryPostProcessor實現(xiàn)了PriorityOrdered接口, 且權(quán)重為1 => 權(quán)重越低, 越優(yōu)先執(zhí)行


    在這里插入圖片描述
  14. 由spring掃描出來的BeanFactoryPostProcessor實現(xiàn)了PriorityOrdered接口, 且權(quán)重為2 => 權(quán)重越低, 越優(yōu)先執(zhí)行


    在這里插入圖片描述

3.2 執(zhí)行流程及原理

3.2.1 處理手動添加的BeanFactoryPostProcessor(包含BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor)

在這里插入圖片描述

在這里插入圖片描述

3.2.2 執(zhí)行BeanDefinitionRegistryPostProcessor類型且實現(xiàn)了PriorityOrdered接口的后置處理器

此步驟非常重要,后續(xù)將專門為此步驟總結(jié)一篇博客, 來具體描述它做了些什么事

在這里插入圖片描述

3.2.3 執(zhí)行BeanDefinitionRegistryPostProcessor類型且實現(xiàn)了Ordered接口的后置處理器兜挨, 執(zhí)行過程與第二步大同小異

在這里插入圖片描述

3.2.4 執(zhí)行BeanDefinitionRegistryPostProcessor類型且未實現(xiàn)Ordered接口和PriorityOrdered接口的后置處理器膏孟, 執(zhí)行過程與第三步大同小異

在這里插入圖片描述

3.2.5 處理BeanDefinitionRegistryPostProcessor類型的BeanFactoryPostProcessor

  • 上述4步都是調(diào)用BeanDefinitionRegistryPostProcessor類型的后置處理器, 后面將開始調(diào)用BeanFactoryPostProcessor類型的后置處理器。因為還有手動添加BeanDefinitionRegistryPostProcessor也是BeanFactoryPostProcessor類型的后置處理器(繼承), 所以此步驟將開始調(diào)用手動添加的BeanDefinitionRegistryPostProcessor后置處理器的BeanFactoryPostProcessor中的方法以及手動添加的BeanFactoryPostProcessor
```java
 // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
 // 這里是第一次調(diào)用手動添加到spring的BeanDefinitionRegistryPostProcessor的重寫B(tài)eanFactoryPostProcessors接口的(postProcessBeanFactory)方法
 // 因為BeanDefinitionRegistryPostProcessor是繼承BeanFactoryPostProcessor類拌汇。所以也重寫了BeanFactoryPostProcessor的方法
 // 在第一次調(diào)用時只調(diào)用了BeanDefinitionRegisterPostProcessor中的方法
 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
 // 這里是第一次調(diào)用手動添加到spring的BeanFactoryPostProcessor
 invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
```
![在這里插入圖片描述](https://upload-images.jianshu.io/upload_images/24982457-9a949fa03072b3e6?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

3.2.6 執(zhí)行以@Component形式添加并實現(xiàn)了PriorityOrdered接口的BeanFactoryPostProcessor后置處理器

在這里插入圖片描述

3.2.7 執(zhí)行以@Component形式添加并實現(xiàn)了Ordered接口的BeanFactoryPostProcessor后置處理器

在這里插入圖片描述

3.3 關(guān)于"3.2.3 執(zhí)行BeanDefinitionRegistryPostProcessor類型且實現(xiàn)了Ordered接口的后置處理器柒桑, 執(zhí)行過程與第二步大同小異"的兩個疑問

  • 原圖


    在這里插入圖片描述
問題 答案
Q1: 為什么這里也執(zhí)行了實現(xiàn)PriorityOrdered接口的后置處理器?上面不是已經(jīng)執(zhí)行過了嗎噪舀? 因為PriorityOrdered接口繼承了Ordered接口, 所以在處理實現(xiàn)Ordered類型的接口時, 也會把實現(xiàn)PriorityOrdered接口的后置處理器也拿出來魁淳。同時之前的確已經(jīng)執(zhí)行過了實現(xiàn)了PriorityOrdered接口的后置處理器(ConfigurationClassPostProcessor), 但這是一個特殊的后置處理器, 因為它,我們才能在后面獲取@Component注解形式添加的后置處理器傅联。最重要的是在執(zhí)行它的時候, bean工廠中只有一個實現(xiàn)了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor類型的后置處理器, 所以spring才用了processedBeans的set集合來存儲已經(jīng)執(zhí)行過的后置處理器
Q2: 為什么只執(zhí)行了postProcessorNames的2,3,4,5下標(biāo)的后置處理器先改? 因為它們都實現(xiàn)了Ordered接口, 盡管有些后置處理器實現(xiàn)的是PriorityOrdered接口, 但PriorityOrdered接口繼承了Ordered接口

三、小結(jié)

  • invokeBeanFactoryPostProcessor方法的主要作用就是調(diào)用后置處理器, 這里最需要主要到的一個后置處理器就是ConfigurationClassPostProcessor, 它不僅做了掃描工作還做了為全配置類生成cglib代理對象的工作(因為它有兩個身份: 一個是BeandefinitionRegistryPostProcessor另一個是BeanFactoryPostProcessor)

  • 關(guān)于BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor后置處理器的區(qū)別和作用

    類型 提供api 作用
    BeanDefinitionRegistryPostProcessor BeanDefinitionRegistry 是一個beanDefinition的注冊器, 一般用它來注冊一個beanDefinition
    BeanFactoryPostProcessor ConfigurableListableBeanFactory 其實就是spring的bean工廠, 只不過是用父類來接收蒸走。 bean工廠都可以拿到了, 我們可以對bean做不可描述的事情了,比如改變bean的class為它創(chuàng)建代理對象,
  • 使用 BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor后置處理器的注意事項

    • 得明白每個后置處理器的執(zhí)行順序 eg:手動添加的BeanDefinitionRegistryPostProcessor類型的后置處理器, 比spring內(nèi)置和以@Component方式添加的后置處理器都先執(zhí)行
    • 熟悉實現(xiàn)不同接口的后置處理器的執(zhí)行順序, eg: BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor類型的后置處理器都是優(yōu)先處理實現(xiàn)PriorityOrdered接口
  • spring源碼學(xué)習(xí)對應(yīng)GitHub 地址https://github.com/AvengerEug/spring/tree/develop/resourcecode-study

  • I am a slow walker, but I never walk backwards.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末貌嫡,一起剝皮案震驚了整個濱河市比驻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌岛抄,老刑警劉巖别惦,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異夫椭,居然都是意外死亡掸掸,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扰付,“玉大人堤撵,你說我怎么就攤上這事∮疠海” “怎么了实昨?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長盐固。 經(jīng)常有香客問我荒给,道長,這世上最難降的妖魔是什么刁卜? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任志电,我火速辦了婚禮,結(jié)果婚禮上蛔趴,老公的妹妹穿的比我還像新娘溪北。我一直安慰自己,他們只是感情好夺脾,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布之拨。 她就那樣靜靜地躺著,像睡著了一般咧叭。 火紅的嫁衣襯著肌膚如雪蚀乔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天菲茬,我揣著相機(jī)與錄音吉挣,去河邊找鬼。 笑死婉弹,一個胖子當(dāng)著我的面吹牛睬魂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播镀赌,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼氯哮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了商佛?” 一聲冷哼從身側(cè)響起喉钢,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎良姆,沒想到半個月后肠虽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡玛追,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年税课,在試婚紗的時候發(fā)現(xiàn)自己被綠了闲延。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡韩玩,死狀恐怖垒玲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情啸如,我是刑警寧澤侍匙,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站叮雳,受9級特大地震影響想暗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜帘不,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一说莫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧寞焙,春花似錦储狭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至呛牲,卻和暖如春刮萌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背娘扩。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工着茸, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人琐旁。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓涮阔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親灰殴。 傳聞我的和親對象是個殘疾皇子敬特,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容