【Spring原始碼分析】非懶載入的單例Bean初始化前後的一些操作

五月的倉頡發表於2017-04-07

前言

之前兩篇文章【Spring原始碼分析】非懶載入的單例Bean初始化過程(上篇)【Spring原始碼分析】非懶載入的單例Bean初始化過程(下篇)比較詳細地分析了非懶載入的單例Bean的初始化過程,整個流程始於AbstractApplicationContext的refresh()方法:

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            initMessageSource();

            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            onRefresh();

            // Check for listener beans and register them.
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            finishRefresh();
        }

        catch (BeansException ex) {
            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();

            // Reset 'active' flag.
            cancelRefresh(ex);

            // Propagate exception to caller.
            throw ex;
        }
    }
}

之前重點分析的是finishBeanFactoryInitialization方法,這個方法完成了所有非懶載入的單例Bean的初始化。今天我回頭重看了一下refresh()方法,發現前面有一些方法還是忽略了沒有去特別在意,其實他們都是Spring整個啟動流程中的重要組成部分,下面就來分析一下finishBeanFactoryInitialization方法前面的一些方法。

obtainFreshBeanFactory方法之前已經詳細分析過了,就從prepareBeanFactory方法開始。

 

PrepareBeanFactory方法

看一下PrepareBeanFactory方法的實現:

 1 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
 2     // Tell the internal bean factory to use the context's class loader etc.
 3     beanFactory.setBeanClassLoader(getClassLoader());
 4     beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
 5     beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this));
 6 
 7     // Configure the bean factory with context callbacks.
 8     beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
 9     beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
10     beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
11     beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
12     beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
13 
14     // BeanFactory interface not registered as resolvable type in a plain factory.
15     // MessageSource registered (and found for autowiring) as a bean.
16     beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
17     beanFactory.registerResolvableDependency(ResourceLoader.class, this);
18     beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
19     beanFactory.registerResolvableDependency(ApplicationContext.class, this);
20 
21     // Detect a LoadTimeWeaver and prepare for weaving, if found.
22     if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
23         beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
24         // Set a temporary ClassLoader for type matching.
25         beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
26     }
27 
28     // Register default environment beans.
29     if (!beanFactory.containsBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
30         Map systemProperties;
31         try {
32             systemProperties = System.getProperties();
33         }
34         catch (AccessControlException ex) {
35             systemProperties = new ReadOnlySystemAttributesMap() {
36                 @Override
37                 protected String getSystemAttribute(String propertyName) {
38                     try {
39                         return System.getProperty(propertyName);
40                     }
41                     catch (AccessControlException ex) {
42                         if (logger.isInfoEnabled()) {
43                             logger.info("Not allowed to obtain system property [" + propertyName + "]: " +
44                                     ex.getMessage());
45                         }
46                         return null;
47                     }
48                 }
49             };
50         }
51         beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, systemProperties);
52     }
53 
54     if (!beanFactory.containsBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
55         Map<String,String> systemEnvironment;
56         try {
57             systemEnvironment = System.getenv();
58         }
59         catch (AccessControlException ex) {
60             systemEnvironment = new ReadOnlySystemAttributesMap() {
61                 @Override
62                 protected String getSystemAttribute(String variableName) {
63                     try {
64                         return System.getenv(variableName);
65                     }
66                     catch (AccessControlException ex) {
67                         if (logger.isInfoEnabled()) {
68                             logger.info("Not allowed to obtain system environment variable [" + variableName + "]: " +
69                                     ex.getMessage());
70                         }
71                         return null;
72                     }
73                 }
74             };
75         }
76         beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, systemEnvironment);
77     }
78 }

首先是第3行,配置當前上下文ClassLoader

接著是第4行,這是一個表達是語言處理器,可以使用#{bean.xxx}的方式來呼叫相關屬性值

接著是第5行,這是一個屬性編輯器,具體沒怎麼用過

接著是第8行,第8行增加了一個ApplicationContextAwareProcessor用於上下文回撥,它是BeanPostProcessor的實現類,跟一下這個介面的兩個方法postProcessBeforeInitialization和postProcessAfterInitialization即可知道這個方法的作用是:

  • 如果Bean是EmbeddedValueResolverAware介面的實現類,則呼叫setEmbeddedValueResolver方法,傳入當前BeanFactory
  • 如果Bean是ResourceLoaderAware介面的實現類,則呼叫setResourceLoader方法,傳入當前上下文ApplicationContext
  • 如果Bean是ApplicationEventPublisherAware的實現類,則呼叫setApplicationEventPublisher方法,傳入當前上下文ApplicationContext
  • 如果Bean是MessageSourceAware的實現類,則呼叫setMessageSource方法,傳入當前上下文ApplicationContext
  • 如果Bean是ApplicationContextAware的實現類,則呼叫setApplicationContext方法,傳入當前上下文ApplicationContext

接著是第9行~第12行,意思是Bean如果是這些介面的實現類,則不會被自動裝配,自動裝配見【Spring9】Autowire(自動裝配)機制

接著是第16行~第19行,意思是修正依賴,這裡是一些自動裝配的特殊規則,比如是BeanFactory介面的實現類,則修正為當前BeanFactory

接著是第22行~第26行,意思是如果自定義的Bean中有定義過一個名為"loadTimeWeaver"的Bean,則會新增一個LoadTimeWeaverAwareProcessor

最後是第29行~第77行,意思是如果自定義的Bean中沒有名為"systemProperties"和"systemEnvironment"的Bean,則註冊兩個Bena,Key為"systemProperties"和"systemEnvironment",Value為Map,這兩個Bean就是一些系統配置和系統環境資訊,具體可以寫這麼一段程式碼測試一下:

public class TestSpring {
    
    @SuppressWarnings("unchecked")
    @Test
    public void testSpring() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring/spring.xml");
        
        Map<String, String> systemPropertiesBean = (Map<String, String>)ac.getBean("systemProperties");
        for (Map.Entry<String, String> entry : systemPropertiesBean.entrySet()) {
            System.out.println(entry.getKey() + "--->" + entry.getValue());
        }
        
        System.out.println("==============================華麗的分隔符==============================");
        Map<String, String> systemEnvironmentBean = (Map<String, String>)ac.getBean("systemEnvironment");
        for (Map.Entry<String, String> entry : systemEnvironmentBean.entrySet()) {
            System.out.println(entry.getKey() + "--->" + entry.getValue());
        }
    }
    
}

涉及個人資訊,執行結果我就不貼了,大家可以自己試試,至此整個PrepareBeanFactory方法的細節已經分析完畢了。

 

invokeBeanFactoryPostProcessors方法

這個是整個Spring流程中非常重要的一部分,是Spring留給使用者的一個非常有用的擴充套件點,BeanPostProcessor介面針對的是每個Bean初始化前後做的操作而BeanFactoryPostProcessor介面針對的是所有Bean例項化前的操作,注意用詞,初始化只是例項化的一部分,表示的是呼叫Bean的初始化方法,BeanFactoryPostProcessor介面方法呼叫時機是任意一個自定義的Bean被反射生成出來前

OK,看一下原始碼:

 1 protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
 2     // Invoke BeanDefinitionRegistryPostProcessors first, if any.
 3     Set<String> processedBeans = new HashSet<String>();
 4     if (beanFactory instanceof BeanDefinitionRegistry) {
 5         BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
 6         List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
 7         List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
 8                 new LinkedList<BeanDefinitionRegistryPostProcessor>();
 9         for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
10             if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
11                 BeanDefinitionRegistryPostProcessor registryPostProcessor =
12                             (BeanDefinitionRegistryPostProcessor) postProcessor;
13                     registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
14                     registryPostProcessors.add(registryPostProcessor);
15             }
16             else {
17                 regularPostProcessors.add(postProcessor);
18             }
19         }
20         Map<String, BeanDefinitionRegistryPostProcessor> beanMap =
21                 beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false);
22         List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans =
23                 new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values());
24         OrderComparator.sort(registryPostProcessorBeans);
25         for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) {
26             postProcessor.postProcessBeanDefinitionRegistry(registry);
27         }
28         invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
29         invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory);
30         invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
31         processedBeans.addAll(beanMap.keySet());
32     }
33     else {
34         // Invoke factory processors registered with the context instance.
35         invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
36     }
37 
38     // Do not initialize FactoryBeans here: We need to leave all regular beans
39     // uninitialized to let the bean factory post-processors apply to them!
40     String[] postProcessorNames =
41         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
42 
43     // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
44     // Ordered, and the rest.
45     List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
46     List<String> orderedPostProcessorNames = new ArrayList<String>();
47     List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
48     for (String ppName : postProcessorNames) {
49         if (processedBeans.contains(ppName)) {
50             // skip - already processed in first phase above
51         }
52         else if (isTypeMatch(ppName, PriorityOrdered.class)) {
53             priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
54         }
55         else if (isTypeMatch(ppName, Ordered.class)) {
56             orderedPostProcessorNames.add(ppName);
57         }
58         else {
59             nonOrderedPostProcessorNames.add(ppName);
60         }
61     }
62 
63     // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
64     OrderComparator.sort(priorityOrderedPostProcessors);
65     invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
66 
67     // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
68     List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
69     for (String postProcessorName : orderedPostProcessorNames) {
70         orderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
71     }
72     OrderComparator.sort(orderedPostProcessors);
73     invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
74 
75     // Finally, invoke all other BeanFactoryPostProcessors.
76     List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
77     for (String postProcessorName : nonOrderedPostProcessorNames) {
78         nonOrderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
79     }
80     invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
81 }

我們可以自己實現BeanFactoryPostProcessor介面並實現postProcessBeanFactory方法,在所有Bean載入的流程開始前,會呼叫一次postProcessBeanFactory方法。分析一下這段程式碼,首先我們使用的是DefaultListableBeanFactory,它是BeanDefinitionRegistry的子類,因此進入第4行的判斷。

整個判斷獲取的是當前有的BeanFactoryPostProcessor並呼叫postProcessBeanFactory,這些BeanFactoryPostProcessor是前置通過AbstractApplicationContext的addBeanFactoryPostProcessor方法新增的而不是配置檔案裡面配置的BeanFactoryPostProcessor的實現Bean,因此這個判斷沒有任何可執行的BeanFactoryPostProcessor。

接著40行~41行這兩行,獲取的是beanDefinitionMap中的Bean,即使用者自定義的Bean。

接著第45行~61行,這裡分出了三個List,表示開發者可以自定義BeanFactoryPostProcessor的呼叫順序,具體為呼叫順序為:

  • 如果BeanFactoryPostProcessor實現了PriorityOrdered介面(PriorityOrdered介面是Ordered的子介面,沒有自己的介面方法定義,只是做一個標記,表示呼叫優先順序高於Ordered介面的子介面),是優先順序最高的呼叫,呼叫順序是按照介面方法getOrder()的實現,對返回的int值從小到大進行排序,進行呼叫
  • 如果BeanFactoryPostProcessor實現了Ordered介面,是優先順序次高的呼叫,將在所有實現PriorityOrdered介面的BeanFactoryPostProcessor呼叫完畢之後,依據getOrder()的實現對返回的int值從小到大排序,進行呼叫
  • 不實現Ordered介面的BeanFactoryPostProcessor在上面的BeanFactoryPostProcessor呼叫全部完畢之後進行呼叫,呼叫順序就是Bean定義的順序

最後的第63行~第80行就是按照上面的規則依次先將BeanFactoryPostProcessor介面對應的實現類例項化出來並呼叫postProcessBeanFactory方法。

 

registerBeanPostProcessors方法

接下來看看registerBeanPostProcessors方法,顧名思義,就是註冊自定義的BeanPostProcessor介面。看一下程式碼實現:

 1 protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
 2     String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
 3 
 4     // Register BeanPostProcessorChecker that logs an info message when
 5     // a bean is created during BeanPostProcessor instantiation, i.e. when
 6     // a bean is not eligible for getting processed by all BeanPostProcessors.
 7     int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
 8     beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
 9 
10     // Separate between BeanPostProcessors that implement PriorityOrdered,
11     // Ordered, and the rest.
12     List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
13     List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
14     List<String> orderedPostProcessorNames = new ArrayList<String>();
15     List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
16     for (String ppName : postProcessorNames) {
17         if (isTypeMatch(ppName, PriorityOrdered.class)) {
18             BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
19             priorityOrderedPostProcessors.add(pp);
20             if (pp instanceof MergedBeanDefinitionPostProcessor) {
21                 internalPostProcessors.add(pp);
22             }
23         }
24         else if (isTypeMatch(ppName, Ordered.class)) {
25             orderedPostProcessorNames.add(ppName);
26         }
27         else {
28             nonOrderedPostProcessorNames.add(ppName);
29         }
30     }
31 
32     // First, register the BeanPostProcessors that implement PriorityOrdered.
33     OrderComparator.sort(priorityOrderedPostProcessors);
34     registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
35 
36     // Next, register the BeanPostProcessors that implement Ordered.
37     List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
38     for (String ppName : orderedPostProcessorNames) {
39         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
40         orderedPostProcessors.add(pp);
41         if (pp instanceof MergedBeanDefinitionPostProcessor) {
42             internalPostProcessors.add(pp);
43         }
44     }
45     OrderComparator.sort(orderedPostProcessors);
46     registerBeanPostProcessors(beanFactory, orderedPostProcessors);
47 
48     // Now, register all regular BeanPostProcessors.
49     List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
50     for (String ppName : nonOrderedPostProcessorNames) {
51         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
52         nonOrderedPostProcessors.add(pp);
53         if (pp instanceof MergedBeanDefinitionPostProcessor) {
54             internalPostProcessors.add(pp);
55         }
56     }
57     registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
58 
59     // Finally, re-register all internal BeanPostProcessors.
60     OrderComparator.sort(internalPostProcessors);
61     registerBeanPostProcessors(beanFactory, internalPostProcessors);
62 
63     beanFactory.addBeanPostProcessor(new ApplicationListenerDetector());
64 }

整體程式碼思路和invokeBeanFactoryPostProcessors方法類似,但是這裡不會呼叫BeanPostProcessor介面的方法,而是把每一個BeanPostProcessor介面實現類例項化出來並按照順序放入一個List中,到時候按順序進行呼叫。

具體程式碼思路可以參考invokeBeanFactoryPostProcessors,這裡就根據程式碼總結一下BeanPostProcessor介面的呼叫順序:

  • 優先呼叫PriorityOrdered介面的子介面,呼叫順序依照介面方法getOrder的返回值從小到大排序
  • 其次呼叫Ordered介面的子介面,呼叫順序依照介面方法getOrder的返回值從小到大排序
  • 接著按照BeanPostProcessor實現類在配置檔案中定義的順序進行呼叫
  • 最後呼叫MergedBeanDefinitionPostProcessor介面的實現Bean,同樣按照在配置檔案中定義的順序進行呼叫

 

initMessageSource方法

initMessageSource方法用於初始化MessageSource,MessageSource是Spring定義的用於實現訪問國際化的介面,看一下原始碼:

 1 protected void initMessageSource() {
 2     ConfigurableListableBeanFactory beanFactory = getBeanFactory();
 3     if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
 4         this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
 5         // Make MessageSource aware of parent MessageSource.
 6         if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
 7             HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
 8             if (hms.getParentMessageSource() == null) {
 9                 // Only set parent context as parent MessageSource if no parent MessageSource
10                 // registered already.
11                 hms.setParentMessageSource(getInternalParentMessageSource());
12             }
13         }
14         if (logger.isDebugEnabled()) {
15             logger.debug("Using MessageSource [" + this.messageSource + "]");
16         }
17     }
18     else {
19         // Use empty MessageSource to be able to accept getMessage calls.
20         DelegatingMessageSource dms = new DelegatingMessageSource();
21         dms.setParentMessageSource(getInternalParentMessageSource());
22         this.messageSource = dms;
23             beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
24         if (logger.isDebugEnabled()) {
25             logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
26                     "': using default [" + this.messageSource + "]");
27         }
28     }
29 }

這個if...else...判斷比較好理解:

  • 如果自定義了名為"messageSource"的Bean,那麼直接例項化Bean,該Bean必須是MessageSource介面的實現Bean,順便該Bean如果是HierarchicalMessageSource介面的實現類,強轉為HierarchicalMessageSource介面,並設定一下parentMessageSource
  • 如果沒有自定義名為"messageSource"的Bean,那麼會預設註冊一個DelegatingMessageSource並加入

 

initApplicationEventMulticaster方法

initApplicationEventMulticaster方法是用於初始化上下文事件廣播器的,看一下原始碼:

 1 protected void initApplicationEventMulticaster() {
 2     ConfigurableListableBeanFactory beanFactory = getBeanFactory();
 3     if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
 4         this.applicationEventMulticaster =
 5                 beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
 6         if (logger.isDebugEnabled()) {
 7             logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
 8         }
 9     }
10     else {
11         this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
12         beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
13         if (logger.isDebugEnabled()) {
14             logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
15                     APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
16                     "': using default [" + this.applicationEventMulticaster + "]");
17         }
18     }
19 }

和initMessageSource方法一樣,這個if...else...判斷也比較好理解:

  • 如果自定義了名為"applicationEventMulticaster"的Bean,就例項化自定義的Bean,但自定義的Bean必須是ApplicationEventMulticaster介面的實現類
  • 如果沒有自定義名為"ApplicationEventMulticaster"的Bean,那麼就註冊一個型別為SimpleApplicationEventMulticaster的Bean

整個Spring的廣播器是觀察者模式的經典應用場景之一,這個之後有時間會分析Spring廣播器的原始碼。

 

onRefresh方法

接下來簡單說說onRefresh方法,AbstractApplicationContext中這個方法沒有什麼定義:

/**
 * Template method which can be overridden to add context-specific refresh work.
 * Called on initialization of special beans, before instantiation of singletons.
 * <p>This implementation is empty.
 * @throws BeansException in case of errors
 * @see #refresh()
 */
protected void onRefresh() throws BeansException {
    // For subclasses: do nothing by default.
}

看一下注釋的意思:一個模板方法,重寫它的作用是新增特殊上下文重新整理的工作,在特殊Bean的初始化時、初始化之前被呼叫。在Spring中,AbstractRefreshableWebApplicationContext、GenericWebApplicationContext、StaticWebApplicationContext都實現了這個方法。

 

registerListeners方法

registerListeners方法顧名思義,用於註冊監聽器:

 1 /**
 2  * Add beans that implement ApplicationListener as listeners.
 3  * Doesn't affect other listeners, which can be added without being beans.
 4  */
 5 protected void registerListeners() {
 6     // Register statically specified listeners first.
 7     for (ApplicationListener listener : getApplicationListeners()) {
 8         getApplicationEventMulticaster().addApplicationListener(listener);
 9     }
10     // Do not initialize FactoryBeans here: We need to leave all regular beans
11     // uninitialized to let post-processors apply to them!
12     String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
13     for (String lisName : listenerBeanNames) {
14         getApplicationEventMulticaster().addApplicationListenerBean(lisName);
15     }
16 }

這裡先向applicationEventMulticaster中註冊一些靜態的、特定的監聽器。

 

finishRefresh方法

最後一步,結束Spring上下文重新整理:

 1 /**
 2  * Finish the refresh of this context, invoking the LifecycleProcessor's
 3  * onRefresh() method and publishing the
 4  * {@link org.springframework.context.event.ContextRefreshedEvent}.
 5  */
 6 protected void finishRefresh() {
 7     // Initialize lifecycle processor for this context.
 8     initLifecycleProcessor();
 9 
10     // Propagate refresh to lifecycle processor first.
11     getLifecycleProcessor().onRefresh();
12 
13     // Publish the final event.
14     publishEvent(new ContextRefreshedEvent(this));
15 }

這裡面分了三步,第一步,初始化LifecycleProcessor介面:

 1 protected void initLifecycleProcessor() {
 2     ConfigurableListableBeanFactory beanFactory = getBeanFactory();
 3     if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
 4         this.lifecycleProcessor =
 5                 beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
 6         if (logger.isDebugEnabled()) {
 7             logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
 8         }
 9     }
10     else {
11         DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
12         defaultProcessor.setBeanFactory(beanFactory);
13         this.lifecycleProcessor = defaultProcessor;
14         beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
15         if (logger.isDebugEnabled()) {
16             logger.debug("Unable to locate LifecycleProcessor with name '" +
17                     LIFECYCLE_PROCESSOR_BEAN_NAME +
18                     "': using default [" + this.lifecycleProcessor + "]");
19         }
20     }
21 }

流程和initMessageSource方法、initApplicationEventMulticaster方法基本類似:

  • 先找一下有沒有自定義名為"lifecycleProcessor"的Bean,有的話就例項化出來,該Bean必須是LifecycleProcessor的實現類
  • 沒有自定義名為"lifecycleProcessor"的Bean,向Spring上下文中註冊一個型別為DefaultLifecycleProcessor的LifecycleProcessor實現類

第二步,呼叫一下LifecycleProcessor的onRefresh方法。

第三步,由於之前已經初始化了:

 1 public void publishEvent(ApplicationEvent event) {
 2     Assert.notNull(event, "Event must not be null");
 3     if (logger.isTraceEnabled()) {
 4         logger.trace("Publishing event in " + getDisplayName() + ": " + event);
 5     }
 6     getApplicationEventMulticaster().multicastEvent(event);
 7     if (this.parent != null) {
 8         this.parent.publishEvent(event);
 9     }
10 }

 

後記

再看AbstractApplicationContext的refresh方法,從中讀到了很多細節:

  • Spring預設載入的兩個Bean,systemProperties和systemEnvironment,分別用於獲取環境資訊、系統資訊
  • BeanFactoryPostProcessor介面用於在所有Bean例項化之前呼叫一次postProcessBeanFactory
  • 可以通過實現PriorityOrder、Order介面控制BeanFactoryPostProcessor呼叫順序
  • 可以通過實現PriorityOrder、Order介面控制BeanPostProcessor呼叫順序
  • 預設的MessageSource,名為"messageSource"
  • 預設的ApplicationEventMulticaster,名為"applicationEventMulticaster"
  • 預設的LifecycleProcessor,名為"lifecycleProcessor"

除了這些,在整個refresh方法裡還隱藏了許多細節,這裡就不一一羅列了,多讀原始碼,會幫助我們更好地使用Spring。

相關文章