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.nameuser.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);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM