深入理解Spring容器初始化(二):BeanFactory的初始化

前言

我們知道,spring 的啓動其實就是容器的啓動,而一般情況下,容器指的其實就是上下文 ApplicationContext

AbstractApplicationContext 作爲整個 ApplicationContext 體系中最高級的抽象類,爲除了 ComplexWebApplicationContextSimpleWebApplicationContext 這兩個容器外的全部容器,規定好了 refresh 的整體流程,所有的容器在完成一些自己的初始化配置後,都需要調用該 refresh 方法,依次完成指定內容的初始化。

也就是說,讀懂了 AbstractApplicationContext.refresh() 方法,其實就讀懂了容器的啓動流程:

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {

        // ================= 一、上下文的初始化 =================
        // 準備上下文
        prepareRefresh();
        // 通知子類刷新內部工廠
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        // 準備bean工廠以便在當前上下文中使用
        prepareBeanFactory(beanFactory);

        try {
            // ================= 二、BeanFactory的初始化 =================
            // 對工廠進行默認後置處理
            postProcessBeanFactory(beanFactory);
            // 使用後置處理器對工廠進行處理
            invokeBeanFactoryPostProcessors(beanFactory);
            // 註冊Bean後置處理器
            registerBeanPostProcessors(beanFactory);

            // ================= 三、事件,Bean及其他配置的初始化 =================
            // 初始化此上下文的消息源
            initMessageSource();
            // 爲此上下文初始化事件廣播者
            initApplicationEventMulticaster();
            // 初始化特定上下文子類中的其他特殊bean
            onRefresh();
            // 檢查偵聽器bean並註冊
            registerListeners();
            // 實例化所有非懶加載的剩餘單例
            finishBeanFactoryInitialization(beanFactory);
            // 完成刷新
            finishRefresh();
        }


        // ================= 異常處理 =================
        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
            }
            // 銷燬已創建的單例
            destroyBeans();
            // 重置上下文的激活狀態
            cancelRefresh(ex);
            throw ex;
        }
        finally {
            // 重置內部的一些元數據緩存
            resetCommonCaches();
        }
    }
}

從總體來看,該方法描述的初始化過程大概分爲三步:

筆者將基於 spring 源碼 5.2.x 分支,分別通過五篇文章從源碼分析 spring 容器的初始化過程。

本文是其中的第二篇文章,將介紹 BeanFactory 初始化。

相關文章:

一、對工廠進行默認後置處理

AbstractApplicationContext.postProcessBeanFactory()BeanFactory 的第一步,該過程用於在用戶自定義的 BeanFactoryPostProcessor 前,對 BeanFactory 進行一些默認的配置。

AbstractApplicationContext 中,這個方法是個空實現,需要子類實現它的具體邏輯,但是無外乎都是做以下三件事:

  • BeanFactory 註冊默認的 Bean 後置處理器;
  • BeanFactory 註冊默認的 Bean 作用域;
  • BeanFactory 註冊一些默認的 Bean

我們以一個典型的實現類 AbstractRefreshableWebApplicationContext 爲例:

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 註冊後置處理器ServletContextAwareProcessor
    beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
    beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

    // 註冊web環境下一些必要組件
    WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
    WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}

1、註冊默認Bean後置處理器

postProcessBeanFactory() 最先調用了 BeanFactory.addBeanPostProcessor() 用於註冊 ServletContextAwareProcessor 這個 Bean 後置處理器:

// beanFactory.addBeanPostProcessor
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    // Remove from old position, if any
    this.beanPostProcessors.remove(beanPostProcessor);
    // Track whether it is instantiation/destruction aware
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
        this.hasInstantiationAwareBeanPostProcessors = true;
    }
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
        this.hasDestructionAwareBeanPostProcessors = true;
    }
    // Add to end of list
    this.beanPostProcessors.add(beanPostProcessor);
}

而對於 ServletContextAwareProcessor 這個類,我們只需要關注它實現的 postProcessBeforeInitialization 接口:

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   if (getServletContext() != null && bean instanceof ServletContextAware) {
      ((ServletContextAware) bean).setServletContext(getServletContext());
   }
   if (getServletConfig() != null && bean instanceof ServletConfigAware) {
      ((ServletConfigAware) bean).setServletConfig(getServletConfig());
   }
   return bean;
}

它將向所有實現了 ServletConfigAware 的 bean 註冊 ServletContextServletConfig 這兩個 bean,這也是爲什麼要在 postProcessBeanFactory

beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

忽略 ServletContextAwareServletConfigAware 的原因了,因此 ServletContextAwareProcessor 已經完成了這兩者的功能。

2、註冊默認Bean作用域

registerWebApplicationScopes 方法主要用於註冊 requestsessionglobalSessionapplication 這四個作用域:

public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
                                                @Nullable ServletContext sc) {

    beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
    beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
    if (sc != null) {
        ServletContextScope appScope = new ServletContextScope(sc);
        beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
        // Register as ServletContext attribute, for ContextCleanupListener to detect it.
        sc.setAttribute(ServletContextScope.class.getName(), appScope);
    }

    beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
    beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
    beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
    beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
    if (jsfPresent) {
        FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
    }
}

3、註冊默認Bean

registerEnvironmentBeans 方法用於註冊 contextParameterscontextAttributes 這兩個環境 bean:

public static void registerEnvironmentBeans(ConfigurableListableBeanFactory bf,
                                            @Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {

    if (servletContext != null && !bf.containsBean(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME)) {
        bf.registerSingleton(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME, servletContext);
    }

    if (servletConfig != null && !bf.containsBean(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME)) {
        bf.registerSingleton(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME, servletConfig);
    }

    if (!bf.containsBean(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME)) {
        Map<String, String> parameterMap = new HashMap<>();
        if (servletContext != null) {
            Enumeration<?> paramNameEnum = servletContext.getInitParameterNames();
            while (paramNameEnum.hasMoreElements()) {
                String paramName = (String) paramNameEnum.nextElement();
                parameterMap.put(paramName, servletContext.getInitParameter(paramName));
            }
        }
        if (servletConfig != null) {
            Enumeration<?> paramNameEnum = servletConfig.getInitParameterNames();
            while (paramNameEnum.hasMoreElements()) {
                String paramName = (String) paramNameEnum.nextElement();
                parameterMap.put(paramName, servletConfig.getInitParameter(paramName));
            }
        }
        bf.registerSingleton(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME,
                             Collections.unmodifiableMap(parameterMap));
    }

    if (!bf.containsBean(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME)) {
        Map<String, Object> attributeMap = new HashMap<>();
        if (servletContext != null) {
            Enumeration<?> attrNameEnum = servletContext.getAttributeNames();
            while (attrNameEnum.hasMoreElements()) {
                String attrName = (String) attrNameEnum.nextElement();
                attributeMap.put(attrName, servletContext.getAttribute(attrName));
            }
        }
        bf.registerSingleton(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME,
                             Collections.unmodifiableMap(attributeMap));
    }
}

二、使用後置處理器對工廠進行處理

在調用完 AbstractApplicationContext.postProcessBeanFactory() 後,BeanFactory 中已經具備了一些 spring 默認的配置,此時再調用 AbstractApplicationContext.invokeBeanFactoryPostProcessors 方法,使用用戶提供的工廠後置處理器 BeanFactoryPostProcessorBeanFactory 進行後置處理。

AbstractApplicationContext 中,該方法實現如下:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 藉助後處理委託類調用全部的後置處理器
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    
    // 如果存在loadTimeWeaver這個bean,則會配置上LoadTimeWeaverAwareProcessor這個後置處理器
    // 然後設置臨時的類加載器ContextTypeMatchClassLoader
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

// AbstractApplicationContext
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
    return this.beanFactoryPostProcessors; // 這些是直接註冊到上下文中的BeanFactoryPostProcessor
}

這裏其實主要分爲兩部分邏輯:

  • 藉助後處理器委託類 PostProcessorRegistrationDelegate 完成對 BeanFactory 的後置處理;
  • 如果引入了 AOP ,則需要爲 BeanFactory 設置特殊的類加載器,從而允許生成 Bean 時織入切面邏輯;

第二部分很簡潔,主要的邏輯都在第一部分。

1、後置處理委託類

這裏又出現了一個新類 PostProcessorRegistrationDelegate,該類實際上是一個靜態工具類,專門提供靜態方法以用於處理上下文的後處理操作的,該類總共提供了兩個方法:

  • invokeBeanFactoryPostProcessors():該方法用於對 BeanFactory 進行後置處理;
  • registerBeanPostProcessors():該方法用於向上下文中註冊 Bean 的後置處理器;

2、對BeanFactory進行後置處理

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors() 這個方法非常的長,不過邏輯還是很明確的:

public static void invokeBeanFactoryPostProcessors(
    ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

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

    // 如果BeanFactory實現了BeanDefinitionRegistry接口
    if (beanFactory instanceof BeanDefinitionRegistry) {

        // 將後置處理器分爲兩類:
        // 1.普通的BeanFactoryPostProcessor;
        // 2.BeanFactoryPostProcessor的子類BeanDefinitionRegistryPostProcessor;
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                    (BeanDefinitionRegistryPostProcessor) postProcessor;
                // 若是BeanDefinitionRegistryPostProcessor,則先調用該類的postProcessBeanDefinitionRegistry方法
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            }
            else {
                regularPostProcessors.add(postProcessor);
            }
        }

        // Do not initialize 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<>();

        // 先調用實現了PriorityOrdered接口的BeanDefinitionRegistryPostProcessors
        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);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();

        // 再調用實現了Ordered接口的BeanDefinitionRegistryPostProcessors
        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();

        // 最後調用沒實現PriorityOrdered或者Ordered接口的BeanDefinitionRegistryPostProcessors
        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.
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    // 如果BeanFactory沒有實現BeanDefinitionRegistry接口
    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!
    String[] postProcessorNames =
        beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    // 過濾掉已經調用過的處理器,然後把處理器分爲三類:
    // 1.實現了PriorityOrdered接口的處理器;
    // 2.實現了Ordered接口的處理器;
    // 3.沒有實現PriorityOrdered或Ordered接口的處理器;
    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);
        }
    }

     // 調用實現了PriorityOrdered接口的後置處理器
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // 調用實現了Ordered接口的後置處理器
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    // 調用沒有實現PriorityOrdered或Ordered接口的後置處理器
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

    // 清除元數據
    beanFactory.clearMetadataCache();
}

由於 BeanFactoryPostProcessor 存在一個子接口 BeanDefinitionRegistryPostProcessor,它對應 BeanFactory 的一個子實現 BeanDefinitionRegistry,通過 BeanDefinitionRegistryPostProcessor 可以調整實現了 BeanDefinitionRegistryBeanFactory 中對 Bean 定義的一些信息。

由於 Bean 的定義肯定要比 Bean 的創建更優先,因此需要先執行 BeanDefinitionRegistryPostProcessor,然後再執行 BeanFactoryPostProcessor

同時,又由於 spring 提供了一套排序機制,即處理時優先處理實現了 PriorityOrdered 接口的處理器,再處理實現了 Ordered 接口的處理器,最後再處理兩個接口都不實現的處理器,執行 BeanDefinitionRegistryPostProcessor,與執行 BeanFactoryPostProcessor 時都還要根據排序區分執行順序。

因此,綜合上文,這一步總體流程其實是這樣的:

  • BeanFactory 實現了 BeanDefinitionRegistry 接口,則優先完成此步驟:
    1. 先調用實現了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor
    2. 再調用實現了 Ordered 接口的 BeanDefinitionRegistryPostProcessor
    3. 最後調用沒有實現上述兩接口的 BeanDefinitionRegistryPostProcessor
  • 不管是否實現了 BeanDefinitionRegistry,都完成此步驟:
    1. 先調用實現了 PriorityOrdered 接口的 BeanFactoryPostProcessor
    2. 再調用實現了 Ordered 接口的 BeanFactoryPostProcessor
    3. 最後調用沒有實現上述兩接口的 BeanFactoryPostProcessor

三、註冊Bean後置處理器

AbstractApplicationContext.registerBeanPostProcessors()BeanFactory 加載的第三步。這一步與調用 BeanFactory 一樣,都通過後置處理委託類 PostProcessorRegistrationDelegate 進行:

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

registerBeanPostProcessors 與 上文調用 BeanFactory 後置處理器邏輯基本一致:

public static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // Register BeanPostProcessorChecker that logs an info message when
    // a bean is created during BeanPostProcessor instantiation, i.e. when
    // a bean is not eligible for getting processed by all BeanPostProcessors.
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // 依然將後置處理器分爲三類:
    // 1.實現了PriorityOrdered接口的處理器;
    // 2.實現了Ordered接口的處理器;
    // 3.沒有實現PriorityOrdered或Ordered接口的處理器;
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            // 這裏是用於框架內部使用的後置處理器
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // 註冊實現了PriorityOrdered接口的後置處理器
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // 註冊實現了Ordered接口的後置處理器
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // 註冊沒有實現PriorityOrdered或Ordered接口的後置處理器
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // 註解框架內部使用的後置處理器
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // 重新註冊ApplicationListenerDetector,保證該處理器總是位於處理器鏈的最後一位,從而總是在最後被執行
    // 該後置處理器用於支持spring的事件機制
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

上述這些代碼的邏輯也很明確:

  1. 先註冊實現了 PriorityOrdered 接口的 BeanPostProcessor
  2. 再註冊實現了 Ordered 接口的 BeanPostProcessor
  3. 接着註冊沒有實現上述兩接口的 BeanPostProcessor
  4. 然後再註冊框架內部使用的 BeanPostProcessor
  5. 最後註冊 ApplicationListenerDetector ,保證該後置處理器總是位於處理器鏈的末尾;

總結

當上下文刷新完畢,並且準備好了新的 BeanFactory 後,需要對 BeanFactory 進行三步操作以完成 BeanFactory 本身的初始化:

  1. postProcessBeanFactory:對 bean 工廠進行預處理,包括註冊一些默認的 Bean 後置處理器,設置默認的 Bean 作用域,以及註冊默認 Bean 等;

  2. invokeBeanFactoryPostProcessors:使用註冊到上下文中的 BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessorBeanFactory 進行後置處理;

  3. registerBeanPostProcessors:註冊 bean 的後處理器,包括用戶自定義的、spring 內部使用的,以及用於支持事件機制的 ApplicationListenerDetector

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章