1. 程式人生 > >spring5 原始碼深度解析-----ApplicationContext容器refresh過程

spring5 原始碼深度解析-----ApplicationContext容器refresh過程

在之前的博文中我們一直以BeanFactory介面以及它的預設實現類XmlBeanFactory為例進行分析,但是Spring中還提供了另一個介面ApplicationContext,用於擴充套件BeanFactory中現有的功能。
ApplicationContext和BeanFactory兩者都是用於載入Bean的,但是相比之下,ApplicationContext提供了更多的擴充套件功能,簡而言之:ApplicationContext包含BeanFactory的所有功能。通常建議比優先使用ApplicationContext,除非在一些限制的場合,比如位元組長度對記憶體有很大的影響時(Applet),絕大多數“典型的”企業應用系統,ApplicationContext就是需要使用的。

那麼究竟ApplicationContext比BeanFactory多了哪些功能?首先我們來看看使用兩個不同的類去載入配置檔案在寫法上的不同如下程式碼:

//使用BeanFactory方式載入XML.
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));

//使用ApplicationContext方式載入XML.
ApplicationContext bf = new ClassPathXmlApplicationContext("beanFactoryTest.xml");

接下來我們就以ClassPathXmlApplicationContext作為切入點,開始對整體功能進行分析。首先看下其建構函式:

public ClassPathXmlApplicationContext() {
}

public ClassPathXmlApplicationContext(ApplicationContext parent) {
    super(parent);
}

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
    this(new String[] {configLocation}, true, null);
}

public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {
    this(configLocations, true, null);
}

public ClassPathXmlApplicationContext(String[] configLocations, @Nullable ApplicationContext parent)
        throws BeansException {

    this(configLocations, true, parent);
}

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {
    this(configLocations, refresh, null);
}

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
        throws BeansException {
    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        refresh();
    }
}

設定路徑是必不可少的步驟,ClassPathXmlApplicationContext中可以將配置檔案路徑以陣列的方式傳入,ClassPathXmlApplicationContext可以對陣列進行解析並進行載入。而對於解析及功能實現都在refresh()中實現。

設定配置路徑

在ClassPathXmlApplicationContext中支援多個配置檔案以陣列方式同時傳入,以下是設定配置路徑方法程式碼:

public void setConfigLocations(@Nullable String... locations) {
    if (locations != null) {
        Assert.noNullElements(locations, "Config locations must not be null");
        this.configLocations = new String[locations.length];
        for (int i = 0; i < locations.length; i++) {
            this.configLocations[i] = resolvePath(locations[i]).trim();
        }
    }
    else {
        this.configLocations = null;
    }
}

其中如果給定的路徑中包含特殊符號,如${var},那麼會在方法resolvePath中解析系統變數並替換

擴充套件功能

設定了路徑之後,便可以根據路徑做配置檔案的解析以及各種功能的實現了。可以說refresh函式中包含了幾乎ApplicationContext中提供的全部功能,而且此函式中邏輯非常清晰明瞭,使我們很容易分析對應的層次及邏輯,我們看下方法程式碼:

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        //準備重新整理的上下文 環境  
        prepareRefresh();
        //初始化BeanFactory,並進行XML檔案讀取  
        /* 
         * ClassPathXMLApplicationContext包含著BeanFactory所提供的一切特徵,在這一步驟中將會複用 
         * BeanFactory中的配置檔案讀取解析及其他功能,這一步之後,ClassPathXmlApplicationContext 
         * 實際上就已經包含了BeanFactory所提供的功能,也就是可以進行Bean的提取等基礎操作了。 
         */  
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        //對beanFactory進行各種功能填充  
        prepareBeanFactory(beanFactory);
        try {
            //子類覆蓋方法做額外處理  
            /* 
             * Spring之所以強大,為世人所推崇,除了它功能上為大家提供了便利外,還有一方面是它的 
             * 完美架構,開放式的架構讓使用它的程式設計師很容易根據業務需要擴充套件已經存在的功能。這種開放式 
             * 的設計在Spring中隨處可見,例如在本例中就提供了一個空的函式實現postProcessBeanFactory來 
             * 方便程式猿在業務上做進一步擴充套件 
             */ 
            postProcessBeanFactory(beanFactory);
            //啟用各種beanFactory處理器  
            invokeBeanFactoryPostProcessors(beanFactory);
            //註冊攔截Bean建立的Bean處理器,這裡只是註冊,真正的呼叫實在getBean時候 
            registerBeanPostProcessors(beanFactory);
            //為上下文初始化Message源,即不同語言的訊息體,國際化處理  
            initMessageSource();
            //初始化應用訊息廣播器,並放入“applicationEventMulticaster”bean中  
            initApplicationEventMulticaster();
            //留給子類來初始化其它的Bean  
            onRefresh();
            //在所有註冊的bean中查詢Listener bean,註冊到訊息廣播器中  
            registerListeners();
            //初始化剩下的單例項(非惰性的)  
            finishBeanFactoryInitialization(beanFactory);
            //完成重新整理過程,通知生命週期處理器lifecycleProcessor重新整理過程,同時發出ContextRefreshEvent通知別人  
            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();
        }
    }
}

我們簡單的分析下程式碼的步驟:
(1)初始化前的準備工作,例如對系統屬性或者環境變數進行準備及驗證。
在某種情況下專案的使用需要讀取某些系統變數,而這個變數的設定很可能會影響著系統的正確性,那麼ClassPathXmlApplicationContext為我們提供的這個準備函式就顯得非常必要,他可以在spring啟動的時候提前對必須的環境變數進行存在性驗證。
(2)初始化BeanFactory,並進行XML檔案讀取。
之前提到ClassPathXmlApplicationContext包含著對BeanFactory所提供的一切特徵,那麼這一步中將會複用BeanFactory中的配置檔案讀取解析其他功能,這一步之後ClassPathXmlApplicationContext實際上就已經包含了BeanFactory所提供的功能,也就是可以進行Bean的提取等基本操作了。
(3)對BeanFactory進行各種功能填充
@Qualifier和@Autowired應該是大家非常熟悉的註解了,那麼這兩個註解正是在這一步驟中增加支援的。
(4)子類覆蓋方法做額外處理。
spring之所以強大,為世人所推崇,除了它功能上為大家提供了遍歷外,還有一方面是它完美的架構,開放式的架構讓使用它的程式設計師很容易根據業務需要擴充套件已經存在的功能。這種開放式的設計在spring中隨處可見,例如本利中就提供了一個空的函式實現postProcessBeanFactory來方便程式設計師在業務上做進一步的擴充套件。
(5)啟用各種BeanFactory處理器
(6)註冊攔截bean建立的bean處理器,這裡只是註冊,真正的呼叫是在getBean時候
(7)為上下文初始化Message源,及對不同語言的小西天進行國際化處理
(8)初始化應用訊息廣播器,並放入“applicationEventMulticaster”bean中
(9)留給子類來初始化其他的bean
(10)在所有註冊的bean中查詢listener bean,註冊到訊息廣播器中
(11)初始化剩下的單例項(非惰性的)
(12)完成重新整理過程,通知生命週期處理器lifecycleProcessor重新整理過程,同時發出ContextRefreshEvent通知別人。
接下來我們就詳細的講解每一個過程

prepareRefresh重新整理上下文的準備工作

/**
 * 準備重新整理上下文環境,設定它的啟動日期和活動標誌,以及執行任何屬性源的初始化。
 * Prepare this context for refreshing, setting its startup date and
 * active flag as well as performing any initialization of property sources.
 */
protected void prepareRefresh() {
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);

    // 在上下文環境中初始化任何佔位符屬性源。(空的方法,留給子類覆蓋)
    initPropertySources();

    // 驗證需要的屬性檔案是否都已放入環境中
    getEnvironment().validateRequiredProperties();

    // 允許收集早期的應用程式事件,一旦有了多播器,就可以釋出……
    this.earlyApplicationEvents = new LinkedHashSet<>();
}

obtainFreshBeanFactory->讀取xml並初始化BeanFactory

obtainFreshBeanFactory方法從字面理解是獲取beanFactory.ApplicationContext是對BeanFactory的擴充套件,在其基礎上添加了大量的基礎應用,obtainFreshBeanFactory正式實現beanFactory的地方,經過這個函式後ApplicationContext就有了BeanFactory的全部功能。我們看下此方法的程式碼:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    //初始化BeanFactory,並進行XML檔案讀取,並將得到的BeanFactory記錄在當前實體的屬性中  
    refreshBeanFactory();
    //返回當前實體的beanFactory屬性 
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (logger.isDebugEnabled()) {
        logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
}

繼續深入到refreshBeanFactory方法中,方法的實現是在AbstractRefreshableApplicationContext中:

@Override
protected final void refreshBeanFactory() throws BeansException {
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        //建立DefaultListableBeanFactory  
        /* 
         * 以前我們分析BeanFactory的時候,不知道是否還有印象,宣告方式為:BeanFactory bf =  
         * new XmlBeanFactory("beanFactoryTest.xml"),其中的XmlBeanFactory繼承自DefaulltListableBeanFactory; 
         * 並提供了XmlBeanDefinitionReader型別的reader屬性,也就是說DefaultListableBeanFactory是容器的基礎。必須 
         * 首先要例項化。 
         */  
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        //為了序列化指定id,如果需要的話,讓這個BeanFactory從id反序列化到BeanFactory物件  
        beanFactory.setSerializationId(getId());
        //定製beanFactory,設定相關屬性,包括是否允許覆蓋同名稱的不同定義的物件以及迴圈依賴以及設定  
        //@Autowired和Qualifier註解解析器QualifierAnnotationAutowireCandidateResolver  
        customizeBeanFactory(beanFactory);
        //載入BeanDefiniton  
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
            //使用全域性變數記錄BeanFactory例項。  
            //因為DefaultListableBeanFactory型別的變數beanFactory是函式內部的區域性變數,  
            //所以要使用全域性變數記錄解析結果  
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

載入BeanDefinition

在第一步中提到了將ClassPathXmlApplicationContext與XMLBeanFactory建立的對比,除了初始化DefaultListableBeanFactory外,還需要XmlBeanDefinitionReader來讀取XML,那麼在loadBeanDefinitions方法中首先要做的就是初始化XmlBeanDefinitonReader,我們跟著到loadBeanDefinitions(beanFactory)方法體中,我們看到的是在AbstractXmlApplicationContext中實現的,具體程式碼如下:

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    // Configure the bean definition reader with this context's
    // resource loading environment.
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // Allow a subclass to provide custom initialization of the reader,
    // then proceed with actually loading the bean definitions.
    initBeanDefinitionReader(beanDefinitionReader);
    loadBeanDefinitions(beanDefinitionReader);
}

在初始化了DefaultListableBeanFactory和XmlBeanDefinitionReader後,就可以進行配置檔案的讀取了。繼續進入到loadBeanDefinitions(beanDefinitionReader)方法體中,程式碼如下:

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    Resource[] configResources = getConfigResources();
    if (configResources != null) {
        reader.loadBeanDefinitions(configResources);
    }
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
        reader.loadBeanDefinitions(configLocations);
    }
}

因為在XmlBeanDefinitionReader中已經將之前初始化的DefaultListableBeanFactory註冊進去了,所以XmlBeanDefinitionReader所讀取的BeanDefinitionHolder都會註冊到DefinitionListableBeanFactory中,也就是經過這個步驟,DefaultListableBeanFactory的變數beanFactory已經包含了所有解析好的配置。

功能擴充套件

如上圖所示prepareBeanFactory(beanFactory)就是在功能上擴充套件的方法,而在進入這個方法前spring已經完成了對配置的解析,接下來我們詳細分析下次函式,進入方法體:

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // Tell the internal bean factory to use the context's class loader etc.
    //設定beanFactory的classLoader為當前context的classloader  
    beanFactory.setBeanClassLoader(getClassLoader());
    //設定beanFactory的表示式語言處理器,Spring3增加了表示式語言的支援,  
    //預設可以使用#{bean.xxx}的形式來呼叫相關屬性值  
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    //為beanFactory增加了一個的propertyEditor,這個主要是對bean的屬性等設定管理的一個工具
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // Configure the bean factory with context callbacks.
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    //設定了幾個忽略自動裝配的介面
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

    // BeanFactory interface not registered as resolvable type in a plain factory.
    // MessageSource registered (and found for autowiring) as a bean.
    //設定了幾個自動裝配的特殊規則
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    // Register early post-processor for detecting inner beans as ApplicationListeners.
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // Detect a LoadTimeWeaver and prepare for weaving, if found.
    //增加對AspectJ的支援 
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        // Set a temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // Register default environment beans.
    //新增預設的系統環境bean  
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
}

詳細分析下程式碼發現上面函式主要是在以下方法進行了擴充套件:
(1)對SPEL語言的支援
(2)增加對屬性編輯器的支援
(3)增加對一些內建類的支援,如EnvironmentAware、MessageSourceAware的注入
(4)設定了依賴功能可忽略的介面
(5)註冊一些固定依賴的屬性
(6)增加了AspectJ的支援
(7)將相關環境變數及屬性以單例模式註冊 

增加對SPEL語言的支援

Spring表示式語言全稱為“Spring Expression Language”,縮寫為“SpEL”,類似於Struts 2x中使用的OGNL語言,SpEL是單獨模組,只依賴於core模組,不依賴於其他模組,可以單獨使用。
SpEL使用#{…}作為定界符,所有在大框號中的字元都將被認為是SpEL,使用格式如下:

<util:properties id="database" location="classpath:db.properties">  
</util:properties>  
<bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource">  
  <property name="username" value="#{database.user}"></property>  
  <property name="password" value="#{database.pwd}"></property>  
  <property name="driverClassName" value="#{database.driver}"></property>  
  <property name="url" value="#{database.url}"></property>  
</bean>

上面只是列舉了其中最簡單的使用方式,SpEL功能非常強大,使用好可以大大提高開發效率。在原始碼中通過程式碼beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver()),註冊語言解析器,就可以對SpEL進行解析了,那麼之後是在什麼地方呼叫這個解析器的呢?
之前說beanFactory中說過Spring在bean進行初始化的時候會有屬性填充的一步,而在這一步中Spring會呼叫AbstractAutowireCapabelBeanFactory類的applyPropertyValues來進行屬性值得解析。同時這個步驟中一般通過AbstractBeanFactory中的evaluateBeanDefinitionString方法進行SpEL解析,方法程式碼如下:

protected Object evaluateBeanDefinitionString(String value, BeanDefinition beanDefinition) {  
    if (this.beanExpressionResolver == null) {  
        return value;  
    }  
    Scope scope = (beanDefinition != null ? getRegisteredScope(beanDefinition.getScope()) : null);  
    return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));  
} 

BeanFactory的後處理

BeanFactory作為spring中容器功能的基礎,用於存放所有已經載入的bean,為例保證程式上的高可擴充套件性,spring針對BeanFactory做了大量的擴充套件,比如我們熟悉的PostProcessor就是在這裡實現的。接下來我們就深入分析下BeanFactory後處理

啟用註冊的BeanFactoryPostProcessor

在正是介紹BeanFactoryPostProcessor的後處理前我們先簡單的瞭解下其用法,BeanFactoryPostProcessor介面跟BeanPostProcessor類似,都可以對bean的定義(配置元資料)進行處理,也就是說spring IoC容器允許BeanFactoryPostProcessor在容器實際例項化任何其他的bean之前讀取配置元資料,並可能修改他。也可以配置多個BeanFactoryPostProcessor,可以通過order屬性來控制BeanFactoryPostProcessor的執行順序(此屬性必須當BeanFactoryPostProcessor實現了Ordered的介面時才可以賒賬,因此在實現BeanFactoryPostProcessor時應該考慮實現Ordered介面)。
如果想改變世界的bean例項(例如從配置元資料建立的物件),那最好使用BeanPostProcessor。同樣的BeanFactoryPostProcessor的作用域範圍是容器級別的,它只是和你鎖使用的容器有關。如果你在容器中定義了一個BeanFactoryPostProcessor,它僅僅對此容器中的bean進行後置處理。BeanFactoryPostProcessor不會對定義在另一個容器中的bean進行後置處理,即使這兩個容器都在同一層次上。在spring中存在對於BeanFactoryPostProcessor的典型應用,如PropertyPlaceholderConfigurer。

BeanFactoryPostProcessor的典型應用:PropertyPlaceholderConfigurer

有時候我們在閱讀spring的配置檔案中的Bean的描述時,會遇到類似如下情況:

<bean id="user" class="com.yhl.myspring.demo.applicationcontext.User">
    <property name="name" value="${user.name}"/>
    <property name="birthday" value="${user.birthday"/>
</bean>

這其中出現了變數:user.name、user.name、{user.birthday},這是spring的分散配置,可以在另外的配置檔案中為user.name、user.birthday指定值,例如在bean.properties檔案中定義:

user.name = xiaoming
user.birthday = 2019-04-19

當訪問名為user的bean時,其name屬性就會被字串xiaoming替換,那spring框架是怎麼知道存在這樣的配置檔案呢,這個就是PropertyPlaceholderConfigurer,需要在配置檔案中新增一下程式碼:

<bean id="userHandler" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:bean.properties</value>
        </list>
    </property>
</bean>

在這個bean中指定了配置檔案的位置。其實還是有個問題,這個userHandler只不過是spring框架管理的一個bean,並沒有被別的bean或者物件引用,spring的beanFactory是怎麼知道這個需要從這個bean中獲取配置資訊呢?我們看下PropertyPlaceholderConfigurer這個類的層次結構,如下圖: 

從上圖中我們可以看到PropertyPlaceholderConfigurer間接的繼承了BeanFactoryPostProcessor介面,這是一個很特別的介面,當spring載入任何實現了這個介面的bean的配置時,都會在bean工廠載入所有bean的配置之後執行postProcessBeanFactory方法。在PropertyResourceConfigurer類中實現了postProcessBeanFactory方法,在方法中先後呼叫了mergeProperties、convertProperties、processProperties這三個方法,分別得到配置,將得到的配置轉換為合適的型別,最後將配置內容告知BeanFactory。
正是通過實現BeanFactoryPostProcessor介面,BeanFactory會在例項化任何bean之前獲得配置資訊,從而能夠正確的解析bean描述檔案中的變數引用。

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    try {
        Properties mergedProps = this.mergeProperties();
        this.convertProperties(mergedProps);
        this.processProperties(beanFactory, mergedProps);
    } catch (IOException var3) {
        throw new BeanInitializationException("Could not load properties", var3);
    }
}

自定義BeanFactoryPostProcessor

編寫實現了BeanFactoryPostProcessor介面的MyBeanFactoryPostProcessor的容器後處理器,如下程式碼:

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("對容器進行後處理。。。。");
    }
}

然後在配置檔案中註冊這個bean,如下:

<bean id="myPost" class="com.yhl.myspring.demo.applicationcontext.MyBeanFactoryPostProcessor"></bean>

最後編寫測試程式碼:

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        User user = (User)context.getBean("user");
        System.out.println(user.getName());

    }
}

啟用BeanFactoryPostProcessor

在瞭解BeanFactoryPostProcessor的用法後我們便可以深入的研究BeanFactoryPostProcessor的呼叫過程了,其是在方法invokeBeanFactoryPostProcessors(beanFactory)中實現的,進入到方法內部:

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

    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    // 1、首先呼叫BeanDefinitionRegistryPostProcessors
    Set<String> processedBeans = new HashSet<>();

    // beanFactory是BeanDefinitionRegistry型別
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        // 定義BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        // 定義BeanDefinitionRegistryPostProcessor集合
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

        // 迴圈手動註冊的beanFactoryPostProcessors
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            // 如果是BeanDefinitionRegistryPostProcessor的例項話,則呼叫其postProcessBeanDefinitionRegistry方法,對bean進行註冊操作
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                // 如果是BeanDefinitionRegistryPostProcessor型別,則直接呼叫其postProcessBeanDefinitionRegistry
                BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            }
            // 否則則將其當做普通的BeanFactoryPostProcessor處理,直接加入regularPostProcessors集合,以備後續處理
            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<>();

        // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
        // 首先呼叫實現了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集合
        registryProcessors.addAll(currentRegistryProcessors);
        // 呼叫所有實現了PriorityOrdered的的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法,註冊bean
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        // 清空currentRegistryProcessors,以備下次使用
        currentRegistryProcessors.clear();

        // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
        // 其次,呼叫實現了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集合
        registryProcessors.addAll(currentRegistryProcessors);
        // 呼叫所有實現了PriorityOrdered的的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法,註冊bean
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        // 清空currentRegistryProcessors,以備下次使用
        currentRegistryProcessors.clear();

        // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
        // 最後,呼叫其他的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集合
            registryProcessors.addAll(currentRegistryProcessors);
            // 呼叫其他的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法,註冊bean
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 清空currentRegistryProcessors,以備下次使用
            currentRegistryProcessors.clear();
        }

        // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
        // 呼叫所有BeanDefinitionRegistryPostProcessor(包括手動註冊和通過配置檔案註冊)
        // 和BeanFactoryPostProcessor(只有手動註冊)的回撥函式-->postProcessBeanFactory
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    // 2、如果不是BeanDefinitionRegistry的例項,那麼直接呼叫其回撥函式即可-->postProcessBeanFactory
    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!
    // 3、上面的程式碼已經處理完了所有的BeanDefinitionRegistryPostProcessors和手動註冊的BeanFactoryPostProcessor
    // 接下來要處理通過配置檔案註冊的BeanFactoryPostProcessor
    // 首先獲取所有的BeanFactoryPostProcessor(注意:這裡獲取的集合會包含BeanDefinitionRegistryPostProcessors)
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, Ordered, and the rest.
    // 這裡,將實現了PriorityOrdered,Ordered的處理器和其他的處理器區分開來,分別進行處理
    // PriorityOrdered有序處理器
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    // Ordered有序處理器
    List<String> orderedPostProcessorNames = new ArrayList<>();
    // 無序處理器
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
        // 判斷processedBeans是否包含當前處理器(processedBeans中的處理器已經被處理過);如果包含,則不做任何處理
        if (processedBeans.contains(ppName)) {
            // skip - already processed in first phase above
        }
        else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            // 加入到PriorityOrdered有序處理器集合
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            // 加入到Ordered有序處理器集合
            orderedPostProcessorNames.add(ppName);
        }
        else {
            // 加入到無序處理器集合
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    // 首先呼叫實現了PriorityOrdered介面的處理器
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    // 其次,呼叫實現了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();
}

迴圈遍歷  BeanFactoryPostProcessor 中的 postProcessBeanFactory 方法

private static void invokeBeanFactoryPostProcessors(
        Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

    for (BeanFactoryPostProcessor postProcessor : postProcessors) {
        postProcessor.postProcessBeanFactory(beanFactory);
    }
}

註冊BeanPostProcessor

在上文中提到了BeanFactoryPostProcessor的呼叫,接下來我們就探索下BeanPostProcessor。但這裡並不是呼叫,而是註冊,真正的呼叫其實是在bean的例項化階段進行的,這是一個很重要的步驟,也是很多功能BeanFactory不知道的重要原因。spring中大部分功能都是通過後處理器的方式進行擴充套件的,這是spring框架的一個特寫,但是在BeanFactory中其實並沒有實現後處理器的自動註冊,所以在呼叫的時候如果沒有進行手動註冊其實是不能使用的。但是ApplicationContext中卻添加了自動註冊功能,如自定義一個後處理器:

public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("befor");
        return null;
    }
}

然後在配置檔案中新增bean的配置:

<bean class="com.yhl.myspring.demo.applicationcontext.MyInstantiationAwareBeanPostProcessor"/>

這樣的話再使用BeanFactory的方式進行載入的bean在載入時不會有任何改變的,而在使用ApplicationContext方式獲取的bean時就會打印出“before”,而這個特性就是咋registryBeanPostProcessor方法中完成的。
我們繼續深入分析registryBeanPostProcessors的方法實現:

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
public static void registerBeanPostProcessors(
        ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

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

    /* 
     * BeanPostProcessorChecker是一個普通的資訊列印,可能會有些情況當spring的配置中的後
     * 處理器還沒有被註冊就已經開了bean的初始化,這時就會打印出BeanPostProcessorChecker中
     * 設定的資訊
     */
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    //使用PriorityOrdered來保證順序
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    //使用Ordered來保證順序
    List<String> orderedPostProcessorNames = new ArrayList<>();
    //無序BeanPostProcessor
    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的BeanPostProcessor
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    //註冊實現了Ordered的BeanPostProcessor
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
    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);

    //註冊所有的無序的BeanPostProcessor
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    //註冊所有的內部BeanFactoryProcessor
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // Re-register post-processor for detecting inner beans as ApplicationListeners,
    //新增ApplicationListener探測器
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

我們可以看到先從容器中獲取所有型別為 BeanPostProcessor.class 的Bean的name陣列,然後通過 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); 獲取Bean的例項,最後通過 registerBeanPostProcessors(beanFactory, orderedPostProcessors);將獲取到的BeanPostProcessor例項新增到容器的屬性中,如下

private static void registerBeanPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

    for (BeanPostProcessor postProcessor : postProcessors) {
        beanFactory.addBeanPostProcessor(postProcessor);
    }
}

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

可以看到將 beanPostProcessor 例項新增到容器的 beanPostProcessors 屬性中

初始化Message資源

該方法不是很重要,留在以後分析吧。。。

初始事件廣播器

初始化ApplicationEventMulticaster是在方法initApplicationEventMulticaster()中實現的,進入到方法體,如下:

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    // 1、預設使用內建的事件廣播器,如果有的話.
    // 我們可以在配置檔案中配置Spring事件廣播器或者自定義事件廣播器
    // 例如: <bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster"></bean>
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
    }
    // 2、否則,新建一個事件廣播器,SimpleApplicationEventMulticaster是spring的預設事件廣播器
    else {
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
    }
}

通過原始碼可以看到其實現邏輯與initMessageSource基本相同,其步驟如下:
(1)查詢是否有name為applicationEventMulticaster的bean,如果有放到容器裡,如果沒有,初始化一個系統預設的SimpleApplicationEventMulticaster放入容器
(2)查詢手動設定的applicationListeners,新增到applicationEventMulticaster裡
(3)查詢定義的型別為ApplicationListener的bean,設定到applicationEventMulticaster
(4)初始化完成、對earlyApplicationEvents裡的事件進行通知(此容器僅僅是廣播器未建立的時候儲存通知資訊,一旦容器建立完成,以後均直接通知)
(5)在系統操作時候,遇到的各種bean的通知事件進行通知
可以看到的是applicationEventMulticaster是一個標準的觀察者模式,對於他內部的監聽者applicationListeners,每次事件到來都會一一獲取通知。

註冊監聽器

protected void registerListeners() {
    // Register statically specified listeners first.
    // 首先,註冊指定的靜態事件監聽器,在spring boot中有應用
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let post-processors apply to them!
    // 其次,註冊普通的事件監聽器
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // Publish early application events now that we finally have a multicaster...
    // 如果有早期事件的話,在這裡進行事件廣播
    // 因為前期SimpleApplicationEventMulticaster尚未註冊,無法釋出事件,
    // 因此早期的事件會先存放在earlyApplicationEvents集合中,這裡把它們取出來進行釋出
    // 所以早期事件的釋出時間節點是早於其他事件的
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    // 早期事件廣播器是一個Set<ApplicationEvent>集合,儲存了無法釋出的早期事件,當SimpleApplicationEventMulticaster
    // 建立完之後隨即進行釋出,同事也要將其儲存的事件釋放
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

我們來看一下Spring的事件監昕的簡單用法

定義監聽事件

public class TestEvent extends ApplicationonEvent { 
    public String msg;
    public TestEvent (Object source ) {
        super (source );
    }
    public TestEvent (Object source , String msg ) { 
        super(source);
        this.msg = msg ; 
    }
    public void print () { 
        System.out.println(msg) ;
    }
}

定義監昕器

public class TestListener implement ApplicationListener { 
    public void onApplicationEvent (ApplicationEvent event ) { 
        if (event instanceof TestEvent ) { 
            TestEvent testEvent = (TestEvent) event ;
            testEvent print () ;
        }
    }
}

新增配置檔案

<bean id=” testListener” class=” com.test.event.TestListener ” />

測試

@Test
public void MyAopTest() {
    ApplicationContext ac = new ClassPathXmlApplicationContext("spring-aop.xml");
    TestEvent event = new TestEvent (“hello” ,”msg”) ;
    context.publishEvent(event);
}

原始碼分析

protected void publishEvent(Object event, ResolvableType eventType) {
    Assert.notNull(event, "Event must not be null");
    if (logger.isTraceEnabled()) {
        logger.trace("Publishing event in " + getDisplayName() + ": " + event);
    }

    // Decorate event as an ApplicationEvent if necessary
    ApplicationEvent applicationEvent;
    //支援兩種事件1、直接繼承ApplicationEvent,2、其他時間,會被包裝為PayloadApplicationEvent,可以使用getPayload獲取真實的通知內容
    if (event instanceof ApplicationEvent) {
        applicationEvent = (ApplicationEvent) event;
    }
    else {
        applicationEvent = new PayloadApplicationEvent<Object>(this, event);
        if (eventType == null) {
            eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
        }
    }

    // Multicast right now if possible - or lazily once the multicaster is initialized
    if (this.earlyApplicationEvents != null) {
        //如果有預製行新增到預製行,預製行在執行一次後被置為null,以後都是直接執行
        this.earlyApplicationEvents.add(applicationEvent);
    }
    else {
        //廣播event事件
        getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
    }

    // Publish event via parent context as well...
    //父bean同樣廣播
    if (this.parent != null) {
        if (this.parent instanceof AbstractApplicationContext) {
            ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
        }
        else {
            this.parent.publishEvent(event);
        }
    }
}

查詢所有的監聽者,依次遍歷,如果有執行緒池,利用執行緒池進行傳送,如果沒有則直接傳送,如果針對比較大的併發量,我們應該採用執行緒池模式,將傳送通知和真正的業務邏輯進行分離

public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
        Executor executor = getTaskExecutor();
        if (executor != null) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    invokeListener(listener, event);
                }
            });
        }
        else {
            invokeListener(listener, event);
        }
    }
}

呼叫invokeListener

protected void invokeListener(ApplicationListener listener, ApplicationEvent event) {
    ErrorHandler errorHandler = getErrorHandler();
    if (errorHandler != null) {
        try {
            listener.onApplicationEvent(event);
        }
        catch (Throwable err) {
            errorHandler.handleError(err);
        }
    }
    else {
        try {
            listener.onApplicationEvent(event);
        }
        catch (ClassCastException ex) {
            // Possibly a lambda-defined listener which we could not resolve the generic event type for
            LogFactory.getLog(getClass()).debug("Non-matching event type for listener: " + listener, ex);
        }
    }
}

初始化其他的單例Bean(非延遲載入的)

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // Initialize conversion service for this context.
    // 判斷有無ConversionService(bean屬性型別轉換服務介面),並初始化
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME)
            && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }

    //
    // Register a default embedded value resolver if no bean post-processor
    // (such as a PropertyPlaceholderConfigurer bean) registered any before:
    // at this point, primarily for resolution in annotation attribute values.
    // 如果beanFactory中不包含EmbeddedValueResolver,則向其中新增一個EmbeddedValueResolver
    // EmbeddedValueResolver-->解析bean中的佔位符和表示式
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
    // 初始化LoadTimeWeaverAware型別的bean
    // LoadTimeWeaverAware-->載入Spring Bean時織入第三方模組,如AspectJ
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    // Stop using the temporary ClassLoader for type matching.
    // 釋放臨時類載入器
    beanFactory.setTempClassLoader(null);

    // Allow for caching all bean definition metadata, not expecting further changes.
    // 凍結快取的BeanDefinition元資料
    beanFactory.freezeConfiguration();

    // Instantiate all remaining (non-lazy-init) singletons.
    // 初始化其他的非延遲載入的單例bean
    beanFactory.preInstantiateSingletons();
}

我們重點看  beanFactory.preInstantiateSingletons();

@Override
public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
        logger.trace("Pre-instantiating singletons in " + this);
    }

    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof FactoryBean) {
                    final FactoryBean<?> factory = (FactoryBean<?>) bean;
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                        ((SmartFactoryBean<?>) factory)::isEagerInit,
                                getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
            }
            else {
                getBean(beanName);
            }
        }
    }

}

完成重新整理過程,通知生命週期處理器lifecycleProcessor重新整理過程,同時發出ContextRefreshEvent通知

protected void finishRefresh() {
    // Clear context-level resource caches (such as ASM metadata from scanning).
    // 清空資源快取
    clearResourceCaches();

    // Initialize lifecycle processor for this context.
    // 初始化生命週期處理器
    initLifecycleProcessor();

    // Propagate refresh to lifecycle processor first.
    // 呼叫生命週期處理器的onRefresh方法
    getLifecycleProcessor().onRefresh();

    // Publish the final event.
    // 推送容器重新整理事件
    publishEvent(new ContextRefreshedEvent(this));

    // Participate in LiveBeansView MBean, if active.
    LiveBeansView.registerApplicationContext(this);
}

&n