1. 程式人生 > >Spring IoC 容器的擴充套件

Spring IoC 容器的擴充套件

# 前言 本系列全部基於 `Spring 5.2.2.BUILD-SNAPSHOT` 版本。因為 Spring 整個體系太過於龐大,所以只會進行關鍵部分的原始碼解析。 本篇文章主要介紹 Spring IoC 容器的功能擴充套件。 # 正文 我們平時在使用 Spring 時,大多不會直接使用 `BeanFactory`,使用比較多的是 `ApplicationContext`;那麼在 Spring 中 `BeanFactory` 和 `ApplicationContext` 有什麼區別呢? * `BeanFactory` 這個介面提供了高階配置的機制的管理物件,是一個基本的 IoC 的容器。 * `ApplicationContext` 是 `BeanFactory` 的一個子介面,提供了 `BeanFactory` 的全部功能,並且在此基礎上還提供了: * 面向切面 (AOP) * 配置元資訊 (Configuration Metadata) * 資源管理 (Resources) * 事件 (Events) * 國際化 (i18n) * 註解 (Annotations) * Environment 抽象 (Environment Abstraction) > 真正的底層 IoC 容器是 `BeanFactory` 的實現類,`ApplicationContext` 中的 `getBean()` 其實都是委託給 `DefaultListableBeanFactory` 來實現。 其中核心流程都在 `AbstractApplicationContext#refresh()` 方法中,我們直接從這個方法開始。 ## 容器重新整理 ### AbstractApplicationContext#refresh ```java public void refresh() throws BeansException, IllegalStateException { // 加鎖 synchronized (this.startupShutdownMonitor) { // 準備重新整理的上下文環境,見下文詳解 prepareRefresh(); // 獲取重新整理後的beanFactory,一般都是建立一個DefaultListableBeanFactory,見下文詳解 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 使用當前上下文環境準備beanFactory,見下文詳解 prepareBeanFactory(beanFactory); try { // beanFactory的後置處理,子類實現,這也算是beanFactory的擴充套件點 // AbstractRefreshableWebApplicationContext在這個方法內加入了request和session的作用域 postProcessBeanFactory(beanFactory); // 呼叫所有BeanFactoryPostProcessors的實現類,見下文詳解 invokeBeanFactoryPostProcessors(beanFactory); // 註冊BeanPostProcessors,見下文詳解 registerBeanPostProcessors(beanFactory); // 初始化訊息資源,這裡不做過多分析 initMessageSource(); // 初始化事件傳播器,這裡不做過多分析 initApplicationEventMulticaster(); // 在特殊的上下文環境中初始化指定的bean,模板方法留給子類實現 onRefresh(); // 註冊監聽器,這裡不做過多分析 registerListeners(); // 例項化所有非延遲載入的單例bean,見下文詳解 finishBeanFactoryInitialization(beanFactory); // 完成上下文的重新整理,呼叫生命週期處理器的onRefresh()並且釋出上下文重新整理完成事件,這裡不做過多分析 finishRefresh(); } // 省略異常處理 finally { // 重置快取,例如方法、欄位等 resetCommonCaches(); } } } ``` 上面方法就是上下文重新整理的流程, 其中關於訊息資源和事件的處理這裡就不分析了,後續可能會單獨分析一下 Spring 中的事件。 ### 上下文重新整理前的環境準備 #### AbstractApplicationContext#prepareRefresh ```java protected void prepareRefresh() { // 記錄開始時間 this.startupDate = System.currentTimeMillis(); // 上下文關閉標識設定為 false this.closed.set(false); // 上下文啟用標識設定為 true this.active.set(true); // 初始化佔位符屬性資源,該方法是留給子類實現的,預設什麼也不做 initPropertySources(); // 驗證需要的屬性檔案是否都已經放入環境中 getEnvironment().validateRequiredProperties(); if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); } else { // 在上下文重新整理前重置監聽器 this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } this.earlyApplicationEvents = new LinkedHashSet<>(); } ``` ### 獲得新的 BeanFactory #### AbstractApplicationContext#obtainFreshBeanFactory ```java protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 重新整理 bean 工廠,見下文詳解 refreshBeanFactory(); // 返回 bean 工廠,見下文詳解 return getBeanFactory(); } ``` #### AbstractRefreshableApplicationContext#refreshBeanFactory ```java protected final void refreshBeanFactory() throws BeansException { // 如果有beanFactory if (hasBeanFactory()) { // 銷燬所有的單例bean destroyBeans(); // 關閉beanFactory,也就是將beanFactory設定為null closeBeanFactory(); } try { // 建立 DefaultListableBeanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); // 指定序列化id beanFactory.setSerializationId(getId()); // 定製beanFactory,設定相關屬性 customizeBeanFactory(beanFactory); // 載入beanDefinition loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { // 加鎖,將beanFactory賦值給全域性變數 this.beanFactory = beanFactory; } } // 省略異常處理... } ``` #### AbstractRefreshableApplicationContext#getBeanFactory ```java public final ConfigurableListableBeanFactory getBeanFactory() { // 加鎖 synchronized (this.beanFactoryMonitor) { // 如果beanFactory為空丟擲異常 if (this.beanFactory == null) { throw new IllegalStateException("BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext"); } // 返回beanFactory return this.beanFactory; } } ``` ### 對 BeanFactory 進行功能填充 #### AbstractApplicationContext#prepareBeanFactory ```java protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 設定beanFactory的classLoader為當前context的classLoader beanFactory.setBeanClassLoader(getClassLoader()); // 設定beanFactory的表示式語言處理器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); // 為beanFactory增加了一個的propertyEditor,這個主要是對bean的屬性等設定管理的一個工具 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // 新增bean擴充套件,主要是對ApplicationContext新增加的Aware介面進行呼叫 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); // 註冊解決依賴,也就是說我們可以通過依賴注入來注入以下四種類型的bean beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // 將是ApplicationListener型別的bean在BeanPostProcessor的初始化後回撥方法中加入到context的監聽器列表中 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // 增加對AspectJ支援 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // 如果beanFactory不存在名為environment的bean,新增預設的,該bean就和我們正常宣告的單例bean一樣 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } // 如果beanFactory不存在名為systemProperties的bean,新增預設的,該bean就和我們正常宣告的單例bean一樣 if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } // 如果systemEnvironment不存在名為systemEnvironment的bean,新增預設的,該bean就和我們正常宣告的單例bean一樣 if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } } ``` ### 呼叫 BeanFactory 的處理器 #### AbstractApplicationContext#invokeBeanFactoryPostProcessors ```java protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // 例項化並呼叫所有已註冊的BeanFactoryPostProcessor PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } } ``` #### PostProcessorRegistryDelegate#invokeBeanFactoryPostProcessors ```java public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) { Set processedBeans = new HashSet<>(); // 判斷beanFactory是否是BeanDefinitionRegistry型別 // 通常情況下這裡的beanFactory是DefaultListableBeanFactory所以這裡判斷為true if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; // 儲存實現了BeanFactoryPostProcessor bean的集合 List regularPostProcessors = new ArrayList<>(); // 儲存實現了BeanDefinitionRegistryPostProcessor bean的集合 List registryProcessors = new ArrayList<>(); // 遍歷beanFactoryPostProcessors for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { // 找出是BeanDefinitionRegistryPostProcessor型別的並呼叫其postProcessBeanDefinitionRegistry() if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); // 將BeanDefinitionRegistryPostProcessor型別的新增進registryProcessors registryProcessors.add(registryProcessor); } else { // 將BeanFactoryPostProcessor型別的新增進regularPostProcessors regularPostProcessors.add(postProcessor); } } List currentRegistryProcessors = new ArrayList<>(); // 獲取所有BeanDefinitionRegistryPostProcessor型別的beanName String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); // 遍歷postProcessorNames for (String ppName : postProcessorNames) { // 如果實現了PriorityOrdered介面, if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 初始化此bean並新增進currentRegistryProcessors currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); // 將此beanName新增到已處理的記錄中 processedBeans.add(ppName); } } // 排序 sortPostProcessors(currentRegistryProcessors, beanFactory); // 將所有BeanDefinitionRegistryPostProcessor型別並且實現了PriorityOrdered介面的bean新增進registryProcessors registryProcessors.addAll(currentRegistryProcessors); // 遍歷呼叫currentRegistryProcessors中的所有BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry() invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 清空currentRegistryProcessors currentRegistryProcessors.clear(); // 和上面的差不多隻是這次是實現了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的bean,並且沒有處理過的 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的postProcessBeanFactory() invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // 獲取所有BeanFactoryPostProcessor型別的beanName String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); List priorityOrderedPostProcessors = new ArrayList<>(); List orderedPostProcessorNames = new ArrayList<>(); List nonOrderedPostProcessorNames = new ArrayList<>(); // 遍歷postProcessorNames for (String ppName : postProcessorNames) { // 如果已經處理過,直接跳過;因為BeanDefinitionRegistryPostProcessor繼承於BeanFactoryPostProcessor // 所以postProcessorNames也包含BeanDefinitionRegistryPostProcessor型別的bean,這裡會對BeanDefinitionRegistryPostProcessor型別的bean直接跳過 if (processedBeans.contains(ppName)) { } // 如果實現了PriorityOrdered介面,初始化該bean並新增進priorityOrderedPostProcessors else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } // 如果實現了Ordered介面,將beanName新增進orderedPostProcessorNames else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } // 正常的將beanName新增進nonOrderedPostProcessorNames else { nonOrderedPostProcessorNames.add(ppName); } } // 排序,然後呼叫BeanFactoryPostProcessors的postProcessBeanFactory() sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // 和上面的一樣這裡是實現了Ordered介面的 List orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // 和上面的一樣這裡是正常的BeanFactoryPostProcessors List nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); beanFactory.clearMetadataCache(); } ``` 上面程式碼首先找出 `BeanDefinitionRegistryPostProcessor` 和 `BeanFactoryPostProcessor` 型別的 `bean`,然後根據其實現的排序介面,來分別進行初始化以及呼叫其回撥方法。可以把 `PriorityOrdered` 理解為 **超級會員**,`Ordered` 為 **普通會員**,都未實現的理解為 **普通使用者**,優先順序一個比一個高。 我們首先看一下 `BeanFactoryPostProcessor` 介面的定義: ```java @FunctionalInterface public interface BeanFactoryPostProcessor { /** * 容器初始化後,bean例項化之前呼叫,可以在此修改BeanDefinition */ void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; } ``` 可以看出 `BeanFactoryPostProcessor` 介面是 Spring 初始化 `BeanFactory` 時對外暴露的擴充套件點,Spring IoC 容器允許 `BeanFactoryPostProcessor` 在容器例項化任何 `bean` 之前讀取 `bean` 的定義,並可以修改它。 接下里我們看一下 `BeanDefinitionRegistryPostProcessor` 介面的定義: ```java public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; } ``` `BeanDefinitionRegistryPostProcessor` 比 `BeanFactoryPostProcessor` 具有更高的優先順序,從上面解析的程式碼中就可以看出,主要用來在 `BeanFactoryPostProcessor ` 之前註冊其它 `bean` 的定義。 ### 註冊 Bean 的處理器 #### AbstractApplicationContext#registerBeanPostProcessors ```java protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); } //PostProcessorRegistrationDelegate.java public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { // 獲取所有實現了BeanPostProcessor的beanName // 這裡會獲取到AutowiredAnnotationProcessor和CommonAnnotationProcessor後置處理器的beanName String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); // 已經註冊進beanFactory的數量 + 手動註冊的BeanPostProcessorChecker + 實現了BeanPostProcessor還未註冊的bean的數量 int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); // 儲存實現了PriorityOrdered介面的BeanPostProcessors List priorityOrderedPostProcessors = new ArrayList<>(); // 儲存實現了MergedBeanDefinitionPostProcessor介面的BeanPostProcessors List internalPostProcessors = new ArrayList<>(); // 儲存實現了Ordered介面的BeanPostProcessors List orderedPostProcessorNames = new ArrayList<>(); // 儲存正常的BeanPostProcessors List nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { // 如果實現了BeanPostProcessor的bean實現了PriorityOrdered介面 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 獲取bean例項 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); // 新增進priorityOrderedPostProcessors priorityOrderedPostProcessors.add(pp); // 如果bean也實現了MergedBeanDefinitionPostProcessor,則新增進internalPostProcessors if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } // 如果實現了Ordered介面,新增進orderedPostProcessorNames else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } // 否則新增進nonOrderedPostProcessorNames else { nonOrderedPostProcessorNames.add(ppName); } } // 將實現了PriorityOrdered的BeanPostProcessors先排序再註冊進beanFactory sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // 將實現了Order的BeanPostProcessors先排序再註冊進beanFactory List orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String ppName : orderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); // 如果實現了MergedBeanDefinitionPostProcessor if (pp instanceof MergedBeanDefinitionPostProcessor) { // 新增進internalPostProcessors internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors); // 將正常的BeanPostProcessors註冊進beanFactory List nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // 最後將實現MergedBeanDefinitionPostProcessor的BeanPostProcessors先排序再註冊進beanFactory sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // 這裡再次添加了ApplicationListenerDetector(之前在prepareBeanFactory()已經新增過)是為了獲取代理 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); } ``` 上面程式碼最後的部分會把實現了 `MergedBeanDefinitionPostProcessor` 會在最後重新註冊一遍,大家可能會認為這不就重複註冊了嗎,其實不然,`beanFactory#addBeanPostProcessor()` 會首先刪除老的,再重新新增新的。 根據上面程式碼大家也會發現,`ApplicationContext` 會幫我們自動註冊實現了 `BeanPostProcessors` 的 `bean`,而使用 `BeanFactory` 就需要自己手動註冊了。 > 注意:上面只是註冊,真正呼叫是在 `getBean()` 的時候。 ### 初始化非懶載入的單例 bean #### AbstractApplicationContext#finishBeanFactoryInitialization ```java protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { 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)); } if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } beanFactory.setTempClassLoader(null); // 凍結所有的bean定義,也就是bean定義將不被修改或任何進一步的處理 beanFactory.freezeConfiguration(); // 初始化非延遲的單例bean,見下文詳解 beanFactory.preInstantiateSingletons(); } ``` #### DefaultListableBeanFactory#preInstantiateSingletons ```java public void preInstantiateSingletons() throws BeansException { List beanNames = new ArrayList<>(this.beanDefinitionNames); for (String beanName : beanNames) { // 獲取合併的BeanDefinition RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // bean不是抽象類 && bean是單例作用域 && bean不是延遲載入 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // 如果bean的FactoryBean if (isFactoryBean(beanName)) { // 獲取FactoryBean的例項,前面加了&符號 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) ((SmartFactoryBean) factory)::isEagerInit, getAccessControlContext()); } else { // FactoryBean是否提前初始化 isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit()); } // 如果是提前初始化直接呼叫getBean()去初始化bean if (isEagerInit) { getBean(beanName); } } } // 直接呼叫getBean()去初始化bean else { getBean(beanName); } } } for (String beanName : beanNames) { // 獲取上面初始化後的單例bean Object singletonInstance = getSingleton(beanName); // 如果bean實現了SmartInitializingSingleton介面,呼叫afterSingletonsInstantiated() if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } } ``` 上面程式碼中的 `getMergedLocalBeanDefinition()` 在[Spring IoC bean 的建立](https://www.cnblogs.com/leisurexi/p/13196998.html)有解析過,這裡不再贅述。這裡介紹一下 `SmartInitializingSingleton` 介面,先看下該介面的定義: ```java public interface SmartInitializingSingleton { /** * 單例bean初始化完成之後呼叫 */ void afterSingletonsInstantiated(); } ``` 這個介面比較簡單,就一個方法,並且只在 `preInstantiateSingletons()` 中呼叫了,也就是說你直接使用 `BeanFactory` 是不會呼叫該回調方法的。該介面回撥方法在單例 `bean` 初始化完成之後呼叫後執行,屬於 Spring Bean 生命週期的增強。 ### 完成重新整理 #### AbstractApplicationContext#finishRefresh ```java protected void finishRefresh() { // 清除資源快取 clearResourceCaches(); // 為此上下文初始化生命週期處理器,見下文詳解 initLifecycleProcessor(); // 首先將重新整理完畢事件傳播到生命週期處理器,見下詳解 getLifecycleProcessor().onRefresh(); // 釋出上下文重新整理完成的事件 publishEvent(new ContextRefreshedEvent(this)); LiveBeansView.registerApplicationContext(this); } ``` #### AbstractApplicationContext#initLifecycleProcessor ```java protected void initLifecycleProcessor() { // 如果當前beanFactory中含有名稱為lifecycleProcessor的bean定義,初始化該bean並賦值給全域性變數lifecycleProcessor ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) { this.lifecycleProcessor = beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class); } else { // beanFactory中沒有名稱為lifecycleProcessor的bean定義,建立一個DefaultLifecycleProcessor並當做單例bean註冊進beanFactory DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor(); defaultProcessor.setBeanFactory(beanFactory); this.lifecycleProcessor = defaultProcessor; beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor); } } ``` #### DefaultLifecycleProcessor#onRefresh ```java public void onRefresh() { startBeans(true); this.running = true; } private void startBeans(boolean autoStartupOnly) { // 獲取所有實現了Lifecycle或者SmartLifecycle的單例bean Map lifecycleBeans = getLifecycleBeans(); Map phases = new HashMap<>(); // 因為onRefresh()呼叫時該方法時,手動設定了autoStartupOnly為false,所以這裡的bean必需是SmartLifecycle型別並且isAutoStartup()返回true lifecycleBeans.forEach((beanName, bean) -> { if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) { // 獲取bean的階段值(如果沒有實現Phased介面,則值為0) int phase = getPhase(bean); // 拿到存放該階段值的LifecycleGroup,如果為空則新建一個並把當前階段值加入其中 LifecycleGroup group = phases.get(phase); if (group == null) { group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly); phases.put(phase, group); } group.add(beanName, bean); } }); // 如果phases不為空,根據階段值從小到大排序,並呼叫重寫Lifecycle介面的start() if (!phases.isEmpty()) { List keys = new ArrayList<>(phases.keySet()); Collections.sort(keys); for (Integer key : keys) { phases.get(key).start(); } } } ``` # 總結 本文主要介紹了 `ApplicationContext` 整個載入的流程,我們可以重新整理一下思路: 1. 重新整理前的準備,在這裡會記錄整個上下文啟動的開始時間,將啟用標識設定為 `true`,關閉標識設定為 `false`。 2. 建立一個新的 `BeanFactory`,這裡大多數情況下都是 `DefaultListableBeanFactory`。首先會檢測之前有沒有 `BeanFactory`,有的話會先銷燬再重新建立,然後會載入 `bean` 的定義元資訊。 3. 配置 `BeanFactory`,設定 `BeanFactory` 的 `classLoader`、表示式語言處理器、添加了 `ApplicationContext` 新增加的 `Aware` 介面回撥等。 4. 呼叫 `BeanFactory` 的後置處理器,這也是 `BeanFactory` 的擴充套件點;上文有分析過這裡不再贅述。 5. 註冊容器內所有的 `BeanPostProcessors`,上文也分析過,不再贅述;值得注意的是如果單單使用 `BeanFactory` 的話是不會自動註冊的。 6. 初始化訊息資源,這裡沒有過多分析,因為對我們整個流程幾乎沒什麼影響。 7. 初始化事件傳播器。關於 Spring 的事件,我打算後面單獨寫一篇文章來介紹,這裡就沒有多說。 8. 在特殊的上下文環境中初始化指定的bean,模板方法留給子類實現。 9. 註冊監聽器,這也留著到 Spring 事件中一起介紹。 10. 初始化所有非延遲載入的單例 `bean`,並且會回撥實現了 `SmartInitializingSingleton` 介面的 `afterSingletonsInstantiated()`,這個介面算是 `bean` 生命週期的增強。 11. 完成上下文的重新整理,呼叫生命週期處理器的 `onRefresh()` 並且釋出上下文重新整理完成事件。 > 最後,我模仿 Spring 寫了一個精簡版,程式碼會持續更新。地址:[https://github.com/leisurexi/tiny-spring](https://github.com/leisurexi/tiny-spr