前言
之前兩篇文章【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。