Bean 生命週期的詳細步驟
第一階段:Bean 的元數據配置與容器啓動
配置元數據:首先,你需要通過 XML、Java 註解(如 @Component, @Service, @Autowired)或 Java 配置類(@Configuration, @Bean)來定義 Bean。
容器啓動:Spring 容器(如 ApplicationContext)啓動,加載並解析這些配置元數據,生成每個 Bean 的 BeanDefinition 對象,它包含了創建一個 Bean 所需的所有信息(如類名、作用域、是否懶加載等)。
第二階段:Bean 的實例化與初始化(核心生命週期)
1. 實例化(Instantiation)
描述:容器首先會調用 Bean 的構造函數(或工廠方法)來創建一個新的實例。此時只是一個簡單的 Java 對象,還沒有進行依賴注入,我們可以把它比作“新生兒”。
擴展點:無直接擴展點。
2. 依賴注入(Populate Properties)
描述:Spring 根據配置(如 @Autowired, @Value)將所需的依賴注入到 Bean 的對應屬性中。這一步填充了 Bean 的“血肉”。
擴展點:無直接擴展點。
3. Aware 接口回調(Aware Interface Injection)
描述:如果 Bean 實現了各種 Aware 接口,Spring 會在此階段回調相應的方法,將一些容器相關的對象(如 BeanNameAware, BeanFactoryAware, ApplicationContextAware)注入到 Bean 中。
擴展點:
BeanNameAware:設置 Bean 的 ID/Name。
BeanFactoryAware:設置當前的 BeanFactory。
ApplicationContextAware:設置當前的 ApplicationContext(功能最全)。
EnvironmentAware:設置 Environment 對象(用於獲取配置文件屬性)等。
4. BeanPostProcessor 前置處理
描述:這是極其重要的擴展點。所有實現了 BeanPostProcessor 接口的 Bean,它們的 postProcessBeforeInitialization 方法會在這個階段被調用。它可以對 Bean 進行包裝或增強,返回一個可能是代理對象的 Bean。
擴展點:BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName)
5. 初始化(Initialization)
描述:Bean 的“成人禮”。在這個階段,Bean 的初始化邏輯會被執行。
a. InitializingBean 接口:如果 Bean 實現了 InitializingBean 接口,會調用其 afterPropertiesSet() 方法。
b. 自定義初始化方法:調用通過 @Bean(initMethod = "...") 或 XML 中 init-method 屬性指定的自定義初始化方法。
擴展點:
InitializingBean.afterPropertiesSet()
自定義 init-method
6. BeanPostProcessor 後置處理
描述:這是另一個極其重要的擴展點。所有 BeanPostProcessor 的 postProcessAfterInitialization 方法會被調用。Spring AOP 就是基於此實現的。如果一個 Bean 需要被代理,通常在這裏返回一個代理對象來包裝目標 Bean。
擴展點:BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName)
7. Bean 就緒(Ready)
描述:經過以上所有步驟,Bean 已經完全創建、初始化並可能被代理。它被存放在 Spring 容器(單例池)中,可以被應用程序正常獲取和使用了。
第三階段:Bean 的使用與銷燬
8. 使用期
描述:在應用程序運行期間,Bean 被其他組件依賴和調用,執行業務邏輯。
9. 銷燬(Destruction)
描述:當 Spring 容器(通常是 ApplicationContext)被關閉時,它會開始銷燬容器中的所有單例 Bean。
a. DisposableBean 接口:如果 Bean 實現了 DisposableBean 接口,會調用其 destroy() 方法。
b. 自定義銷燬方法:調用通過 @Bean(destroyMethod = "...") 或 XML 中 destroy-method 屬性指定的自定義銷燬方法。常用於釋放資源,如關閉數據庫連接、文件句柄等。
擴展點:
DisposableBean.destroy()
自定義 destroy-method
特殊情況的處理
作用域(Scope):上述生命週期主要針對單例(Singleton) Bean。對於原型(Prototype) 作用域的 Bean,Spring 容器只負責到第 6 步(初始化完成),之後就將 Bean 交給客户端,不再管理其生命週期,因此不會調用銷燬方法。
延遲初始化(Lazy):標記為 @Lazy 的 Bean,只有在第一次被請求時才會觸發上述初始化過程,而不是在容器啓動時。
總結與記憶技巧
可以把這個過程想象成一個人的一生:
實例化:出生
依賴注入:接受教育,獲取生存技能(依賴)
Aware 接口:獲得身份ID、認識家庭和社會(容器環境)
BeanPostProcessor(前):步入社會前的指導
初始化:舉行成人禮,開始獨立承擔責任
BeanPostProcessor(後):步入社會後的包裝/歷練(可能被“代理”)
就緒:成為社會棟樑,貢獻力量
銷燬:退休,安享晚年,處理身後事