1. 程式人生 > >(五)SpringBoot啟動過程的分析-重新整理ApplicationContext

(五)SpringBoot啟動過程的分析-重新整理ApplicationContext

-- 以下內容均基於2.1.8.RELEASE版本 緊接著上一篇[(四)SpringBoot啟動過程的分析-預處理ApplicationContext](https://www.cnblogs.com/lukama/p/14583241.html), 本文將分析上下文容器準備完成之後開始執行重新整理流程 ``` // SpringApplication.java private void refreshContext(ConfigurableApplicationContext context) { refresh(context); if (this.registerShutdownHook) { try { context.registerShutdownHook(); } catch (AccessControlException ex) { // Not allowed in some environments. } } } // 真正的refresh方法在AbstractApplicationContext類中 protected void refresh(ApplicationContext applicationContext) { Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext); ((AbstractApplicationContext) applicationContext).refresh(); } // AbstractApplicationContext.java 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) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } } ``` 在refresh方法中清晰的劃分了重新整理容器的步驟。 ## prepareRefresh() 主要用於清除元資料Reader的快取,設定應用程式啟動的時間,設定應用程式的活動標記,初始化屬性源。 ``` // AnnotationConfigServletWebServerApplicationContext.java protected void prepareRefresh() { this.scanner.clearCache(); super.prepareRefresh(); } // AbstractApplicationContext.java protected void prepareRefresh() { // 設定開始執行的時間和活動標記 this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isDebugEnabled()) { if (logger.isTraceEnabled()) { logger.trace("Refreshing " + this); } else { logger.debug("Refreshing " + getDisplayName()); } } // ① initPropertySources(); // ② // Validate that all properties marked as required are resolvable: // see ConfigurablePropertyResolver#setRequiredProperties getEnvironment().validateRequiredProperties(); // ③ // Store pre-refresh ApplicationListeners... if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); } else { // Reset local application listeners to pre-refresh state. this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... this.earlyApplicationEvents = new LinkedHashSet<>(); } ``` ① - 初始化屬性資源 ``` // StandardServletEnvironment.java public void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) { WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig); } // WebApplicationContextUtils.java public static void initServletPropertySources(MutablePropertySources sources, @Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) { Assert.notNull(sources, "'propertySources' must not be null"); String name = StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME; // servletContext不為空且有相關配置的情況 if (servletContext != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) { sources.replace(name, new ServletContextPropertySource(name, servletContext)); } // servletConfig不為空且有相關配置的情況 name = StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME; if (servletConfig != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) { sources.replace(name, new ServletConfigPropertySource(name, servletConfig)); } } ``` 在內部呼叫了WebApplicationContextUtils.initServletPropertySources方法,由名稱可得知,它用於初始化Servlet的屬性資源,在實際執行過程中分別根據ServletContext和ServletConfig的值來判定是否要將指定的配置包裝為ServletContextPropertySource。在實際除錯過程中他們的值都為空,也就是沒有進行任何操作。 ② - 檢查必備屬性,此處是用於檢查哪些屬性是必不可少的,例如可以設定"example.address"這個屬性必須不為空。 ③ - 重新對監聽器排序 ## prepareBeanFactory(beanFactory) ``` // AbstractApplicationContext.java protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 設定類載入器 // Tell the internal bean factory to use the context's class loader etc. beanFactory.setBeanClassLoader(getClassLoader()); // 設定SpringEL表示式解析器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); // 設定屬性編輯器註冊 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,則實際將會指定它注入的是當前設定的BeanFactory // 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); // 新增和移除ApplicationListener // Register early post-processor for detecting inner beans as ApplicationListeners. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // // Detect a LoadTimeWeaver and prepare for weaving, if found. 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. 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()); } } ``` ① - 這裡的忽略依賴介面,是指這些Aware介面的實現類在Spring中將會自動忽略介面實現類中和setter方法入參相同的型別,舉例說明 ``` public interface EnvironmentAware extends Aware { void setEnvironment(Environment environment); } public class MyEnvironmentAware implements Environment { private Environment environment; @Overwired public void setEnvironment(Environment environment) { this.environment = environment; } } ``` 示例中展示瞭如何使用EnvironmentAware介面來實現在自定義程式碼中獲取Environment,上面所說的忽略,是指在Spring自動裝配MyEnvironment這個類的時候,會自動忽略到setEnvironment方法中的Environment物件注入。 在忽略介面的第一行程式碼添加了一個ApplicationContextAwareProcessor,而它則是Spring框架統一來設定這些Aware介面實現類的處理器。 ## postProcessBeanFactory(beanFactory) 在當前AbstractApplicationContext類中的postProcessBeanFactory方法並未實現,由其子類實現。 ``` // AnnotationConfigServletWebServerApplicationContext.java // 實現一 protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { // ① super.postProcessBeanFactory(beanFactory); // ② if (this.basePackages != null && this.basePackages.length > 0) { this.scanner.scan(this.basePackages); } // ③ if (!this.annotatedClasses.isEmpty()) { this.reader.register(ClassUtils.toClassArray(this.annotatedClasses)); } } ``` ① - 呼叫父類的實現 ``` // ServletWebServerApplicationContext.java protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 新增用於處理WebApplicationContextServletContextAware介面的processor beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this)); // 忽略ServletContextAware介面的注入 beanFactory.ignoreDependencyInterface(ServletContextAware.class); registerWebApplicationScopes(); } // 註冊web應用的作用域 public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory, @Nullable ServletContext sc) { beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope()); beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope()); if (sc != null) { ServletContextScope appScope = new ServletContextScope(sc); beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope); // Register as ServletContext attribute, for ContextCleanupListener to detect it. sc.setAttribute(ServletContextScope.class.getName(), appScope); } beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory()); beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory()); beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory()); beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory()); if (jsfPresent) { FacesDependencyRegistrar.registerFacesDependencies(beanFactory); } } ``` ② - 根據basePackage指定的位置進行掃描bean ③ - 根據註解來掃描指定的bean ## invokeBeanFactoryPostProcessors() 主要用於呼叫BeanFactoryPostProcessors的實現 ``` protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // 呼叫BeanFactoryPostProcessor PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } } ``` 在呼叫BeanFactoryPostProcessor時,會首先呼叫BeanDefinitionRegistryPostProcessor, 因為後者是對前者的擴充套件,並且有可能在後者中又重新註冊了前者的其他例項。由於PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法過長,這裡直接寫行內註釋能夠比較 直觀的分析前後關係。 ``` public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. // 已處理的Bean Set processedBeans = new HashSet<>(); // 判斷當前的BeanFactory是否為一個Bean註冊器,實際上就是代表同時實現了BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor介面的實現 // 對於同時實現兩個介面的類,將先呼叫BeanDefinitionRegistryPostProcessor裡面的方法,再呼叫BeanFactoryPostProcessor裡面的方法 // 在呼叫的時候又要區分是實現了PriorityOrdered還是Ordered介面。 if (beanFactory instanceof BeanDefinitionRegistry) { // 轉換為註冊器 BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; // 用於存放常規的BeanFactoryPostProcessor List regularPostProcessors = new ArrayList<>(); // 用於存放BeanFactoryPostProcessor的擴充套件BeanDefinitionRegistryPostProcessor,這裡是一個彙總的列表 List registryProcessors = new ArrayList<>(); // 遍歷傳入的BeanFactoryPostProcessor for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { // 優先執行BeanFactoryPostProcessor的擴充套件類BeanDefinitionRegistryPostProcessor,它的優先順序最高 if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { // 型別轉換 BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; // 呼叫postProcessBeanDefinitionRegistry()方法,內部可能註冊了Bean,也可能重新定義了一些普通的BeanFactoryPostProcessor registryProcessor.postProcessBeanDefinitionRegistry(registry); // 新增到已處理列表 registryProcessors.add(registryProcessor); } else { // 對比上面if程式碼塊會發現,這裡沒有作呼叫,直接先儲存在常規列表內部,因為常規的Processor在呼叫的時候還有其他考慮,接著往下看便是 regularPostProcessors.add(postProcessor); } } // 不要在這裡初始化FactoryBean(請看清是FactoryBean,工廠類,不是類工廠(BeanFactory),他們有巨大的差異),需要保留所有的常規類未初始化,以便使用BeanFactoryPostProcessor對其處理 // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // 根據BeanDefinitionRegistryPostProcessors 實現的介面劃分為三類:實現了PriorityOrdered的、實現了Ordered的以及前面兩者都沒實現的 // Separate between BeanDefinitionRegistryPostProcessors that implement // PriorityOrdered, Ordered, and the rest. // 儲存當前將要處理的BeanDefinitionRegistryPostProcessor列表,每處理完一種分類的就清空 List currentRegistryProcessors = new ArrayList<>(); // 首先呼叫實現了PriorityOrdered介面的BeanDefinitionRegistryPostProcessors // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. // 獲取當前Bean工廠內部所有的,型別為BeanDefinitionRegistryPostProcessor.class的後處理器名稱 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 篩選出實現了PriorityOrdered介面的後處理器,放入當前處理列表 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); // 同時放入已處理列表 processedBeans.add(ppName); } } // 按照優先順序排序 sortPostProcessors(currentRegistryProcessors, beanFactory); // 新增實現了PriorityOrder介面的BeanDefinitionRegistryPostProcessor到它的彙總列表裡面 registryProcessors.addAll(currentRegistryProcessors); // 呼叫所有的BeanDefinitionRegistryPostProcessor例項的postProcessBeanDefinitionRegistry()方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 清除內部的實現了PriorityOrder的BeanDefinitionRegistryPostProcessor currentRegistryProcessors.clear(); // 上面是處理實現了PriorityOrdered介面的,這裡處理實現了Ordered介面的, 為何這裡又獲取了一次postProcessorNames,前面不是才獲取麼? // 這裡獲取一次是因為前面處理的時候有可能又加入了新的BeanDefinitionRegistryPostProcessor // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 清空上一步已經執行過的 currentRegistryProcessors.clear(); // 繼續呼叫普通的BeanDefinitionRegistryPostProcessors // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } // 最後呼叫普通的 BeanFactoryPostProcessor, // Now, invoke the postProcessBeanFactory callback of all processors handled so far. invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); //因為BeanDefinitionRegistryPostProcessor也是繼承了BeanFactoryPostProcessor,,也具有postProcessBeanFactory()方法的,所以也需要執行 invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // 若不是BeanDefinitionRegistry,那就是直接實現了BeanFactoryPostProcessor // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // 下面這部分邏輯就和上面套路一樣,無非處理的是BeanFactoryPostProcessor罷了 // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List priorityOrderedPostProcessors = new ArrayList<>(); List orderedPostProcessorNames = new ArrayList<>(); List nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // Next, invoke the BeanFactoryPostProcessors that implement Ordered. List 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 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(); } ``` ### 小結 BeanFactoryPostProcessors是Spring框架中的一個很重要的擴充套件入口,通過它可以在Bean例項化之前進行一些修改,從型別上分為BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor,在內部處理過程中,前者的優先順序高於後者。與此同時,他們分別還會按照PriorityOrdered > Ordered > 預設 的優先順序順序來進行處理。瞭解他們執行順序這點很重要,後續如有擴充套件需求就可以精準植入自己的邏輯。需要注意的是,這些處理器本身就是用於註冊Bean,因此他們也可以註冊和自己型別一樣的擴充套件類。在使用的時候尤其要注意這點。例如在實現了PriorityOrdered的BeanDefinitionRegistryPostProcessor中 再註冊一個實現了Ordered的BeanDefinitionRegistryPostProcessor,雖然這樣沒問題,但筆者認為這樣程式碼隱藏過深。不利於後期維護。建議使用SPI機制來配置,簡潔明瞭。 ## registerBeanPostProcessors() 主要用於呼叫BeanPostProcessors的實現,區別於上一個章節,本章節處理的是例項化過後的Bean。 ``` // AbstractApplicationContext.java protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { // 呼叫BeanPostProcessor PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); } // PostProcessorRegistrationDelegate.java public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { // 獲取所有的BeanPostProcessor名稱 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); // Register BeanPostProcessorChecker that logs an info message when // a bean is created during BeanPostProcessor instantiation, i.e. when // a bean is not eligible for getting processed by all BeanPostProcessors. // 註冊一個BeanPostProcessorChecker,當一個BeanPostProcessor在例項化期間建立一個Bean的時候,列印日誌 int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); // 按照優先順序整理 // 實現了PriorityOrdered介面的BeanPostProcessor集合 List priorityOrderedPostProcessors = new ArrayList<>(); // 內部定義的BeanPostProcessor集合 List internalPostProcessors = new ArrayList<>(); // 實現了Ordered介面的BeanPostProcessor名稱集合 List orderedPostProcessorNames = new ArrayList<>(); // 未實現排序優先順序介面的BeanPostProcessor名稱集合 List 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 // First, register the BeanPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // 註冊實現了PriorityOrdered介面的BeanPostProcessor // Next, register the BeanPostProcessors that implement Ordered. List 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 // Now, register all regular BeanPostProcessors. List 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); // 重新註冊所有的內部BeanPostProcessor // Finally, re-register all internal BeanPostProcessors. sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // 註冊ApplicationListenerDetector,它將在bean初始化完成之後檢測是否為ApplicationListener,如果是則加入applicationListeners中 // 在Bean銷燬之前,提前從ApplicationEventMulticaster中刪除 // Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc). beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); } ``` ## initMessageSource() 初始化MessageSource,若當前上下文中未定義,則使用父類中的定義 ``` // AbstractApplicationContext.java protected void initMessageSource() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); // Make MessageSource aware of parent MessageSource. if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) { HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource; if (hms.getParentMessageSource() == null) { // Only set parent context as parent MessageSource if no parent MessageSource // registered already. hms.setParentMessageSource(getInternalParentMessageSource()); } } if (logger.isTraceEnabled()) { logger.trace("Using MessageSource [" + this.messageSource + "]"); } } else { // Use empty MessageSource to be able to accept getMessage calls. DelegatingMessageSource dms = new DelegatingMessageSource(); dms.setParentMessageSource(getInternalParentMessageSource()); this.messageSource = dms; beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); if (logger.isTraceEnabled()) { logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]"); } } } ``` ## initApplicationEventMulticaster() 主要用於設定事件釋出器,若當前上下文沒有定義ApplicationEventMulticaster 則使用 SimpleApplicationEventMulticaster ``` // AbstractApplicationContext.java protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); if (logger.isTraceEnabled()) { logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else { this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isTraceEnabled()) { logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " + "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]"); } } } ``` ## onRefresh() 當前類中沒有實現,只是作為一個模板,將由子類來實現 ``` // AbstractApplicationContext.java protected void onRefresh() throws BeansException { // For subclasses: do nothing by default. } // ServletWebServerApplicationContext.java protected void onRefresh() { // 父類中僅僅設定了一下主題,無關緊要 super.onRefresh(); try { // 建立Web伺服器 createWebServer(); } catch (Throwable ex) { throw new ApplicationContextException("Unable to start web server", ex); } } ``` ### 建立Web伺服器 這裡只簡單介紹一下它啟動了內建的Web容器,Web容器的初始化後續會有單獨篇章分析。 ``` private void createWebServer() { // ① WebServer webServer = this.webServer; // ② ServletContext servletContext = getServletContext(); // ③ if (webServer == null && servletContext == null) { ServletWebServerFactory factory = getWebServerFactory(); this.webServer = factory.getWebServer(getSelfInitializer()); } // ④ else if (servletContext != null) { try { getSelfInitializer().onStartup(servletContext); } catch (ServletException ex) { throw new ApplicationContextException("Cannot initialize servlet context", ex); } } // ⑤ initPropertySources(); } ``` ① - 當前應用的WEB伺服器,也就是Servlet容器。 ② - 當前應用的上下文,一個應用使用一個ServletContext來表示。 ③ - 使用ServletWebServerFactory建立一個Servlet容器 ④ - 手動配置上下文的介面。 ⑤ - 初始化配置資訊,實際上就是將環境資訊中的'servletContextInitParams':StubPropertySource 轉換為'servletContextInitParams': ServletContextPropertySource; 將 'servletConfigInitParams': StubPropertySource轉換為'servletConfigInitParams':ServletConfigPropertySource ## registerListeners() 主要用於將獲取到的所有監聽器委託給applicationEventMulticaster。 ``` protected void registerListeners() { // ① // Register statically specified listeners first. 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... Set earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } } ``` ① - 將內部註冊的監聽器委託給廣播器applicationEventMulticaster。 ② - 檢測BeanFactory內部的監聽器 ③ - 釋出早期事件 ## finishBeanFactoryInitialization() 例項化剩下的所有單例Bean(非延遲載入的) ``` // AbstractApplicationContext.java protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // ① // Initialize conversion service for this context. 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. if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // ③ // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. 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. beanFactory.freezeConfiguration(); // ⑤ // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); } ``` ① - 判斷是否有轉換服務 ② - 判斷是否有佔位符解析器 ③ - 註冊LoadTimeWeaverAware ④ - 停止使用臨時的ClassLoader進行型別匹配,實際上它就是空值 ⑤ - 凍結所有的BeanDefinition,通過configurationFrozen = true 和 frozenBeanDefinitionNames(包含所有的BeanDefinition)配合鎖定 ⑥ - 例項化剩下的所有單例Bean(非延遲載入的),其實就是從註冊器快取裡面取出(DefaultSingletonBeanRegistry) ## finishRefresh() ``` // ServletWebServerApplicationContext.java @Override protected void finishRefresh() { // 父類執行finishRefresh super.finishRefresh(); // 啟動web容器 WebServer webServer = startWebServer(); if (webServer != null) { // 釋出web容器啟動完成事件 publishEvent(new ServletWebServerInitializedEvent(webServer, this)); } } // AbstractApplicationContext.java 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. getLifecycleProcessor().onRefresh(); // ④ Publish the final event. publishEvent(new ContextRefreshedEvent(this)); // ⑤ Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); } ``` ① - 清除資源快取 ② - 初始化上下文生命週期 ③ - 傳播重新整理動作至生命週期 ④ - 釋出上下文重新整理完畢事件 ⑤ - 構建當前Bean及其依賴關係的快照,設計用於Spring Tool Suite ## resetCommonCaches() 主要用於清除Spring內部的快取 ``` // AbstractApplicationContext.java protected void resetCommonCaches() { ReflectionUtils.clearCache(); AnnotationUtils.clearCache(); ResolvableType.clearCache(); CachedIntrospectionResults.clearClassLoader(getClassLoader()