Spring5源碼解析4-refresh方法之invokeBeanFactoryPostProcessors

invokeBeanFactoryPostProcessors(beanFactory); 方法源碼如下:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // getBeanFactoryPostProcessors 獲取的是 this.beanFactoryPostProcessors;
    //this.beanFactoryPostProcessors 只能通過 AbstractApplicationContext.addBeanFactoryPostProcessor 方法添加
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
    // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

getBeanFactoryPostProcessors() 方法獲取的是 AbstractApplicationContext#beanFactoryPostProcessors 這個成員變量。

這個成員變量只能通過代碼中手動編碼調用 AbstractApplicationContext#addBeanFactoryPostProcessor 方法來添加新的元素。很明顯,我們這里為空。

invokeBeanFactoryPostProcessors(beanFactory) 方法的主要的邏輯在 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors 方法中:

//PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())源碼
public static void invokeBeanFactoryPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    Set<String> processedBeans = new HashSet<>();

    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

        //beanFactoryPostProcessors是傳進來里的對象,把傳入的對象分類放入 BeanFactoryPostProcessor 和  BeanDefinitionRegistryPostProcessor
        //BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor ,是一個特殊的 BeanFactoryPostProcessor
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                //如果傳入的beanFactoryPostProcessors是它的子類,即:BeanDefinitionRegistryPostProcessor
                //則執行傳入的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            } else {
                regularPostProcessors.add(postProcessor);
            }
        }

        // Do noitialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        // Separate between BeanDefinitionRegistryPostProcessors that implement
        // PriorityOrdered, Ordered, and the rest.
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

        // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.

        //這里只能拿到spring內部的BeanDefinitionRegistryPostProcessor,
        //因為到這里spring還沒有去掃描Bean,獲取不到我們通過@Component標識的自定義BeanDefinitionRegistryPostProcessor
        //一般默認情況下,這里只有一個,BeanName:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
        //對應的BeanClass:ConfigurationClassPostProcessor
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                //beanFactory.getBean, 這里開始創建BeanDefinitionRegistryPostProcessor bean 了
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }

        //排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);

        // registryProcessors 中放的是 BeanDefinitionRegistryPostProcessor
        // 因為這里只執行eanDefinitionRegistryPostProcessor中獨有的方法,而不會執行其父類即BeanFactoryProcessor的方法
        // 所以這里需要把處理器放入一個集合中,后續統一執行父類的方法
        registryProcessors.addAll(currentRegistryProcessors);

        // 執行BeanDefinitionRegistryPostProcessor,currentRegistryProcessors中放的是spring內部的BeanDefinitionRegistryPostProcessor
        // 默認情況下,只有 org.springframework.context.annotation.ConfigurationClassPostProcessor
        // ConfigurationClassPostProcessor 里面就是在執行掃描Bean,并且注冊BeanDefinition
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

        // 清空這個臨時變量,方便后面再使用
        currentRegistryProcessors.clear();

        // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
        // 這里已經可以獲取到我們通過注冊到Spring容器的 BeanDefinitionRegistryPostProcessor 了
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            // 之前優先處理的是實現PriorityOrdered接口的,而PriorityOrdered接口也實現了Ordered接口
            // 所有這里需要把之前已經處理過的給過濾掉
            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);

        // 執行BeanDefinitionRegistryPostProcessor
        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) {
                //執行沒有實現Ordered接口的BeanDefinitionRegistryPostProcessor
                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.
        // List<BeanDefinitionRegistryPostProcessor> registryProcessors
        // 之前已經執行過BeanDefinitionRegistryPostProcessor獨有方法,現在執行其父類方法
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);

        // List<BeanFactoryPostProcessor> regularPostProcessors
        // 執行 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!
    // 獲取 BeanFactoryPostProcessor 的 beanName
    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) {
        // 如果已經被執行過了,就不在執行
        // 因為一開始先獲取的BeanDefinitionRegistryPostProcessor,而BeanDefinitionRegistryPostProcessor繼承了BeanFactoryPostProcessor
        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.
    // 根據不同的優先級,按序執行 BeanFactoryPostProcessor
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    // Finally, invoke all other BeanFactoryPostProcessors.
    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();
}

源碼超級長,我們慢慢來看。

  1. Spring容器使用的 BeanFactoryDefaultListableBeanFactory ,它實現了 BeanDefinitionRegistry 接口,if條件成立。
  2. 優先處理程序傳進來的 beanFactoryPostProcessors ,也就是我們手動調用 AbstractApplicationContext#addBeanFactoryPostProcessor 方法來添加的 BeanFactoryPostProcessor
  3. BeanFactoryPostProcessor 是一個頂級接口,他還有一個子類 BeanDefinitionRegistryPostProcessor 。在該方法中聲明了兩個 List 來存放 BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor ,以便控制這兩個接口方法的執行。
  4. 遍歷傳入的 List<BeanFactoryPostProcessor> beanFactoryPostProcessors ,將其分類放到兩個 List 中。如果傳入的是 BeanDefinitionRegistryPostProcessor 類,則先執行 BeanDefinitionRegistryPostProcessor 類中獨有的方法 postProcessBeanDefinitionRegistry 方法。當然,我們這里傳入的 List<BeanFactoryPostProcessor> beanFactoryPostProcessors 為空。
  5. 第一次執行 beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 方法,從容器中獲取 BeanDefinitionRegistryPostProcessor 類型的Bean的name(這里只是獲取名稱,還沒有實例化Bean)。注意,程序執行到這里,Spring還沒有掃描包,還沒有將項目中的Bean注冊到容器中。默認情況下,這里返回的數據為如下圖所示。回憶一下,這個 BeanDefinition 是在什么時候被加入到 BeanFactory 的呢?是在 AnnotationConfigApplicationContext 的無參構造器中創建 reader 時注冊的 BeanDefinition 。其中BeanName為 org.springframework.context.annotation.internalConfigurationAnnotationProcessor ,對應的Class為 org.springframework.context.annotation.ConfigurationClassPostProcessor Spring5源碼解析4-refresh方法之invokeBeanFactoryPostProcessors
  6. 遍歷這個獲取的 postProcessorNames ,如果實現了 PriorityOrdered 接口,就調用 beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class) 方法,從容器中獲取這個Bean,將其加入到臨時變量 List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors 中。
  7. currentRegistryProcessors 中的元素進行排序,然后執行 BeanDefinitionRegistryPostProcessor 中的特有方法 postProcessBeanDefinitionRegistry 。注意哦,這里沒有執行其父類的方法,而是又將其放到 List<BeanDefinitionRegistryPostProcessor> registryProcessors 中,到后面再執行其父類方法。
  8. 默認情況下,此時 currentRegistryProcessors 中只有一個Bean即: org.springframework.context.annotation.ConfigurationClassPostProcessor (它實現了 PriorityOrdered 接口)。 ConfigurationClassPostProcessor 是一個非常重要的類,我們后面在講。當程序執行完 ConfigurationClassPostProcessorBeanDefinitionRegistryPostProcessor 方法后,我們程序中的Bean就被注冊到了Spring容器中了,需要注意的是,這里還只是注冊了 BeanDefinition ,還沒有創建Bean對象。 Spring5源碼解析4-refresh方法之invokeBeanFactoryPostProcessors Spring5源碼解析4-refresh方法之invokeBeanFactoryPostProcessors
  9. 當第二次執行 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 方法,此時因為之前已經完成了Bean的掃描,所以如果我們有自定義的 BeanDefinitionRegistryPostProcessor 就可以在這里被獲取了。獲取之前,判斷其是否實現 Ordered 接口,并且之前沒有被執行過,則調用 getBean 方法,從容器中獲取該Bean,然后進行排序,執行 postProcessBeanDefinitionRegistry 方法。
  10. 前面已經按順序執行了實現 PriorityOrderedOrdered 接口的 BeanDefinitionRegistryPostProcessor ,最后,執行沒有實現 Ordered 接口的 BeanDefinitionRegistryPostProcessorpostProcessBeanDefinitionRegistry 方法。執行完之后再 BeanDefinitionRegistryPostProcessor 的父類方法 postProcessBeanFactory
  11. 獲取容器中還沒有被執行過的實現 BeanFactoryPostProcessor 接口的Bean,然后按順序執行的 postProcessBeanFactory 。默認情況下,這里會獲取到:

Spring5源碼解析4-refresh方法之invokeBeanFactoryPostProcessors

由于Bean org.springframework.context.annotation.internalConfigurationAnnotationProcessor (對應的Class為 org.springframework.context.annotation.ConfigurationClassPostProcessor )在之前已經被執行了,這里只會執行Bean org.springframework.context.event.internalEventListenerProcessor (對應的Class為 org.springframework.context.event.EventListenerMethodProcessor )的 postProcessBeanFactory 方法,源碼如下:

//org.springframework.context.event.EventListenerMethodProcessor#postProcessBeanFactory 源碼
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    this.beanFactory = beanFactory;

    Map<String, EventListenerFactory> beans = beanFactory.getBeansOfType(EventListenerFactory.class, false, false);
    List<EventListenerFactory> factories = new ArrayList<>(beans.values());
    AnnotationAwareOrderComparator.sort(factories);
    this.eventListenerFactories = factories;
}

未完待續……

源碼學習筆記: https://github.com/shenjianen…

歡迎關注公眾號,一起學習成長。

Spring5源碼解析4-refresh方法之invokeBeanFactoryPostProcessors

原文 

https://segmentfault.com/a/1190000020591860

本站部分文章源于互聯網,本著傳播知識、有益學習和研究的目的進行的轉載,為網友免費提供。如有著作權人或出版方提出異議,本站將立即刪除。如果您對文章轉載有任何疑問請告之我們,以便我們及時糾正。

PS:推薦一個微信公眾號: askHarries 或者qq群:474807195,里面會分享一些資深架構師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發、高性能、分布式、微服務架構的原理,JVM性能優化這些成為架構師必備的知識體系。還能領取免費的學習資源,目前受益良多

轉載請注明原文出處:Harries Blog? » Spring5源碼解析4-refresh方法之invokeBeanFactoryPostProcessors

贊 (0)
分享到:更多 ()

評論 1

  • 昵稱 (必填)
  • 郵箱 (必填)
  • 網址
  1. ado stunt cars 2Tack f?r att du delade inl?gget.回復
手机彩票计划软件超稳