天天看點

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

大家好,又見面了,我是你們的朋友全棧君。

前言

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

ApplicationContext

AbstractApplicationContext

作為整個

ApplicationContext

體系中最進階的抽象類,為除了

ComplexWebApplicationContext

SimpleWebApplicationContext

這兩個容器外的全部容器,規定好了

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();
        }
    }
}           

複制

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

  • 上下文的初始化;
  • BeanFactory

    初始化;
  • 事件,Bean及其他配置的初始化;

筆者将基于 spring 源碼

5.2.x

分支,分别通過五篇文章從源碼分析 spring 容器的初始化過程。

本文是其中的第二篇文章,将介紹

BeanFactory

初始化。

相關文章:

  • 深入了解Spring容器初始化(一):上下文的初始化;
  • 深入了解Spring容器初始化(二):BeanFactory的初始化;
  • 深入了解Spring容器初始化(三):事件及其他配置的初始化;

一、對工廠進行預設後置處理

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 注冊

ServletContext

ServletConfig

這兩個 bean,這也是為什麼要在

postProcessBeanFactory

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

複制

忽略

ServletContextAware

ServletConfigAware

的原因了,是以

ServletContextAwareProcessor

已經完成了這兩者的功能。

2、注冊預設Bean作用域

registerWebApplicationScopes

方法主要用于注冊

request

session

globalSession

application

這四個作用域:

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

方法用于注冊

contextParameters

contextAttributes

這兩個環境 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

方法,使用使用者提供的工廠後置處理器

BeanFactoryPostProcessor

BeanFactory

進行後置處理。

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

可以調整實作了

BeanDefinitionRegistry

BeanFactory

中對

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

    :使用注冊到上下文中的

    BeanFactoryPostProcessor

    BeanDefinitionRegistryPostProcessor

    BeanFactory

    進行後置處理;
  3. registerBeanPostProcessors

    :注冊 bean 的後處理器,包括使用者自定義的、spring 内部使用的,以及用于支援事件機制的

    ApplicationListenerDetector

釋出者:全棧程式員棧長,轉載請注明出處:https://javaforall.cn/170761.html原文連結:https://javaforall.cn