Spring中Bean的生命週期

最近項目有用到對Spring的擴展,順便整理下Spring中Bean的生命週期。

BeanFactory中Bean的生命週期

在這裏插入圖片描述

  1. 當調用者通過getBean(beanName)向容器請求某一個bean時,如果容器註冊了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口,則在實例化Bean之前,將調用接口的postProcessBeforeInstantiation(Class<?> beanClass, String beanName)方法。
  2. 根據配置情況調用Bean構造函數或工廠方實例化Bean。
  3. 如果容器註冊了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口,那麼在實例化Bean後,調用該接口的postProcessAfterInstantiation(Object bean, String beanName),可在這裏對已經實例化的對象做一些“梳妝打扮”。
  4. 如果Bean配置了屬性信息,那麼容器在這一步着手將配置設置到Bean對應的屬性中,不過在設置每個屬性之前將先調用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)方法。
  5. 調用Bean的屬性設置方法設置屬性值。
  6. 如果Bean實現了org.springframework.beans.factory.BeanNameAware接口,則將調用setBeanName(String name)方法,將配置文件中該Bean對應的名稱設置到Bean中。
  7. 如果Bean實現了org.springframework.beans.factory.BeanFactoryAware接口,則將調用setBeanFactory(BeanFactory beanFactory)接口方法,將BeanFactory容器實例設置到Bean中。
  8. 如果BeanFactory裝配了org.springframework.beans.factory.config.BeanPostProcessor後處理器,則將調用BeanPostProcessor接口的Object postProcessBeforeInitialization(Object bean, String beanName)方法對Bean進行加工處理。其中,入參bean爲當前正在處理的bean,而beanName爲當前Bean的配置名,返回的對象爲加工處理後的Bean。用戶可以使用該方法對某些Bean進行特殊處理,甚至改變Bean的行爲。BeanFactory在Spring框架中佔有重要的地位,爲容器提供對Bean進行後續加工處理的切入點,Spring容器所提供的各種”神奇功能“(如AOP、動態代理等)都通過BeanPostProcessor實施。
  9. 如果Bean實現org.springframework.beans.factory.InitializingBean接口,則將調用接口的afterPropertiesSet()方法。
  10. 如果在中通過init-method屬性定義了初始化方法,則將執行這個方法。
  11. BeanPostProcessor後處理器定義了兩個方法:其一是postProcessBeforeInitialization(),在第8步調用,其二是Object postProcessAfterInitialization(Object bean, String beanName),這個方法在此時調用,容器再次獲得對Bean進行加工處理的機會。
  12. 如果在中指定Bean的作用範圍爲scope=“prototype”,則將bean返回給調用者,調用者負責Bean後續生命的管理,Spring不再管理這個Bean的生命週期。如果將作用範圍設置爲scope=“singleton”,則將Bean放入Spring IoC容器的緩存池中,並將Bean引用返回給調用者,Spring繼續對這個Bean進行後續的生命管理。
  13. 對於scope=“singleton”(默認情況),當容器關閉時,將觸發Spring對Bean後續生命週期的管理工作。如果Bean實現了org.springframework.beans.factory.DisposableBean接口,則將調用接口的destroy()方法,可以在此編寫釋放資源、記錄日誌等的操作。
  14. 對於scope="singleton"的Bean,如果通過的destroy-method屬性指定了Bean的銷燬方法,那麼Spring將執行Bean的這個方法,完成Bean資源的釋放等操作。

Bean的完整生命週期從Spring容器着手實例化Bean開始,直到最終銷燬Bean。其中經歷了許多關鍵點,每個關鍵點都涉及特定方法的調用,可以將這些方法大致劃分爲4類。

  • Bean自身的方法:如調用Bean構造函數實例化Bean、調用Setter設置Bean的屬性值及通過的init-method和destroy-method所指定的方法。
  • Bean級生命週期接口方法:如BeanNameAware、BeanFactoryAware、InitializingBean和DisposableBean,這些接口方法Bean類直接實現。
  • 容器級生命週期接口方法:InstantiationAwareBeanPostProcessor和BeanPostProcessor。一般稱它們的實現類爲”後處理器“。後處理器接口一般不由Bean本身實現,它們獨立於Bean,實現類以容器附加裝置的形式註冊到Spring容器中,並通過接口反射爲Spring容器掃描識別。當Spring容器創建任何Bean的時候,這些後處理器都會發生作用,所以這些後處理器的影響是全局性的。當然,用戶可以通過合理地編寫後處理器,讓其僅對感興趣的Bean進行加工處理。
  • 工廠後處理器接口方法:包括AspectJWeavingEnabler、CustomAutowireConfigurer和ConfigurationClassPostProcessor等方法。工廠後處理器也是容器級的,在應用上下文裝配配置文件後立即調用。

Bean級生命週期接口和容器級生命週期接口是個性和共性辯證統一思想的體現,前者解決Bean個性化處理的問題,而後者解決容器中某些Bean共性化處理的問題。

Spring中是否可以註冊多個後處理器呢?答案是肯定的。只要它們同時實現org.springframework.core.Ordered接口,容器將按特定的順序依次調用這些後處理器。

InstantiationAwareBeanPostProcessor其實是BeanPostProcessor接口的子接口,Spring爲其提供了一個適配器類InstantiationAwareBeanPostProcessorAdapter,一般情況下,可以方便地擴展該適配器覆蓋特定的方法以定義特定的實現類。

ApplicationContext中Bean的生命週期

Bean在應用上下文中的生命週期和在BeanFactory中的生命週期類似,不同的是,如果Bean實現了
org.springframework.context.ApplicationContextAware接口,則會增加一個調用該接口方法的setApplicationContext()的步驟。

此外,如果在配置文件中聲明瞭工廠後處理器接口的BeanFactoryPostProessor的實現類,則應用上下文在裝載配置文件之後、初始化Bean實例之前將調用這些BeanFactoryPostProcessor對配置信息進行加工處理。

ApplicationContext和BeanFactory一個最大的不同之處在於:前者會利用Java反射機制自動識別出配置文件中定義的BeanPostProcessor、InstantiationAwareBeanPostProcessor和BeanFactoryPostProcessor,並自動將它們註冊到應用上下文中;而後者需要在代碼中通過手工調用addBeanPostProcessor()方法進行註冊。

參考

《精通Spring 4.x 企業應用開發實戰》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章