如下圖所示,左側是三種類型的 Context:
-
XML 配置方式的 Context;
-
Spring Boot 的 Context;
-
Web 服務的 Context。
不論哪種 Context,創建后都會調用到 AbstractApplicationContext 類的 refresh 方法,流程如下。
-
首先對刷新進行准備,包括設置開始時間、設置激活狀態、初始化 Context 環境中的占位符,這個動作根據子類的需求由子類來執行,然后驗證是否缺失必要的 properties。
-
刷新並獲得內部的 Bean Factory。
-
對 BeanFactory 進行准備工作,比如設置類加載器和后置處理器、配置不進行自動裝配的類型、注冊默認的環境 Bean。
-
為 Context 的子類提供后置處理 BeanFactory 的擴展能力。如果子類想在 Bean 定義加載完成后,開始初始化上下文之前做一些特殊邏輯,可以復寫這個方法。
-
執行 Context 中注冊的 Bean Factory 后綴處理器。這里有兩種后置處理器,一種是可以注冊 Bean 的后綴處理器,另一種是針對 BeanFactory 進行處理的后置處理器。執行的順序是,先按優先級執行可注冊 Bean 的處理器,在按優先級執行針對 BeanFactory的處理器。對 Spring Boot 來說,這一步會進行注解 Bean Definition 的解析。流程如圖右側所示,由 ConfigurationClassPostProcessor 觸發、由 ClassPathBeanDefinitionScanner 解析並注冊到 BeanFactory。
-
按優先級順序在 BeanFactory 中注冊 Bean的后綴處理器,Bean 后置處理器可以在 Bean 初始化前、后執行處理。
-
初始化消息源,消息源用來支持消息的國際化。
-
初始化應用事件廣播器。事件廣播器用來向 ApplicationListener 通知各種應用產生的事件,是一個標准的觀察者模式。
-
是留給子類的擴展步驟,用來讓特定的 Context 子類初始化其他的 Bean。
-
把實現了 ApplicationListener 的 Bean 注冊到事件廣播器,並對廣播器中的早期未廣播事件進行通知。
-
凍結所有 Bean 描述信息的修改,實例化非延遲加載的單例 Bean。
-
完成上下文的刷新工作,調用 LifecycleProcessor 的 onFresh() 方法以及發布 ContextRefreshedEvent 事件。
-
在 finally 中,執行第十三步,重置公共的緩存,比如 ReflectionUtils 中的緩存、 AnnotationUtils 中的緩存等等;
至此,Spring 的 Context 初始化完成。由於篇幅和時間的關系,這里介紹了最主要的主流程,建議課后閱讀源碼來復習這個知識點,補全細節。
內容來自:https://kaiwu.lagou.com/course/courseInfo.htm?courseId=1#/content