1. 程式人生 > >Spring中BeanFactory和ApplicationContext的生命週期及其區別詳解

Spring中BeanFactory和ApplicationContext的生命週期及其區別詳解

Bean的生命週期

在很多技術中,都有生命週期這個概念,如在Android中,有Activity、Fragment等的生命週期;在Web容器中,有Servlet的生命週期。想要成為高階開發者,就必須要深入理解其生命週期。同樣的,在Spring容器中的Bean也有一系列的生命週期,要掌握好Spring,就要先掌握Spring中Bean的生命週期。

在Spring中,可以從兩個層面定義Bean的生命週期:一是Bean的作用範圍,二是Spring例項化Bean時所經歷的一系列階段。下面分別對BeanFactory和ApplicationContext中Bean的生命週期進行分析。

BeanFactory中Bean的生命週期

1、生命週期圖解

這裡寫圖片描述

2、具體過程

根據圖示的生命週期,具體過程如下:

(1)當呼叫者呼叫getBean(beanName)向容器請求某一個Bean時,如果容器註冊了InstantiationAwareBeanPostProcessor介面,則在例項化Bean之前,將呼叫介面的postProcessBeforeInstantiation()方法。

(2)根據配置情況呼叫Bean的建構函式或工廠方法例項化Bean。

(3)如果容器註冊了InstantiationAwareBeanPostProcessor介面,在例項化Bean之後,呼叫該介面的postProcessBeforeInstantiation()方法,對例項化的物件進行一些初始化設定。

(4)如果Bean 配置了屬性資訊,那麼容器在這一步將配置的屬性設定到Bean對應的屬性中,在設定屬性之前將先呼叫InstantiationAwareBeanPostProcessor介面的postProcessPropertyValues()方法。

(5)呼叫Bean中的setXxx()方法設定屬性。

(6)如果Bean實現了BeanNameAware介面,則會呼叫該介面的setBeanName()方法,將配置檔案中該Bean對應的名稱設定到Bean中。

(7)如果Bean實現了BeanFactoryAware介面,則會呼叫該介面的setBeanFactory()方法,將BeanFactory容器例項設定到Bean中。

(8)如果BeanFactory裝配了BeanPostProcessor後處理器,則將呼叫BeanPostProcessor介面的Object postProcessBeforeInitialization方法對Bean進行加工操作。其中,傳入的bean是當前正在處理的bean,而beanName是當前Bean在配置檔案中的配置名,返回加工處理後的bean。使用者可以使用該方法對某些Bean進行特殊的處理。Spring容器所提供的AOP、動態代理等功能都通過BeanPostProcessor實現。

(9)如果Bean實現了InitializingBean介面,則將呼叫該介面的afterPropertiesSet()方法。

(10)如果在配置檔案的bean標籤中通過init-method屬性指定了初始化方法,則會執行這個方法。

(11)如果BeanFactory裝配了BeanPostProcessor後處理器,在這裡則會執行Object postProcessAfterInitialization()方法對Bean進行加工處理。

BeanPostProcessor後處理器定義了兩個方法,分別是postProcessBeforeInitialization()和postProcessAfterInitialization(),分別在第8步和在此處呼叫。

(12)如果在配置檔案中指定了bean的scope=”prototype”,意味著配置的這個bean是多例的,每次獲取該bean都會返回一個新例項化的bean,所以在這一步之後Spring容器不再管理多例的Bean,直接將當前生成的例項返回給使用者。

對於scope=”singleton”的Bean(預設情況),意味著這個Bean是單例的,就需要把這個Bean快取到在Spring IOC容器中,使用者每次獲取時都從這個容器中獲取,並且Spring會對這些Bean進行後續的生命週期管理。

(13)對於單例的Bean,容器關閉時,會觸發Spring對Bean的後續生命週期的管理工作。如果Bean實現了DisposableBean介面,則會呼叫該介面的destroy()方法,在這裡可以進行釋放資源、記錄日誌等操作。

(14)對於單例的Bean,如果在配置檔案中指定了destroy-method屬性,Spring則會執行這個屬性配置的方法,完成Bean資源釋放等操作。

以上生命週期所經歷的方法可大致分為以下四類:

a、Bean自身的方法

包括例項化Bean時Bean的構造方法,設定屬性值時Bean的set方法,以及通過配置檔案配置的init-method和destroy-method指定的方法。

b、Bean級生命週期介面方法

包括BeanNameAware、BeanFactoryAware、InitializingBean和DisposableBean,這些介面方法由Bean直接實現。

c、容器級生命週期介面方法

包括InstantiationAwareBeanPostProcessor和BeanPostProcessor兩個介面。一般稱他們的實現類為後處理器,後處理器介面一般不由Bean本身實現,他們獨立於Bean,實現類以容器附加裝置的形式註冊到Spring容器中,並通過介面反射為Spring容器掃描識別。當Spring容器建立任何Bean時,這些後處理器都會起作用,這些後處理器的影響是全域性性的。

d、工廠後處理器介面方法

包括AspectJWeavingEnabler、CustomAutowireConfigurer、ConfigurationClassPostProcessor等類,都實現了BeanFactoryPostProcessor介面。工廠後處理器也是容器級的,在應用上下文裝配配置檔案後立即呼叫。

Spring容器中還可以註冊多個後處理器,只要他們都實現了Ordered介面,Spring容器就會按照特定的順序依次呼叫這些後處理器。

ApplicationContext中Bean的生命週期

1、生命週期圖解

這裡寫圖片描述

2、具體過程

具體過程與上述BeanFactory中Bean的生命週期類似,這裡不再詳解。

BeanFactory和ApplicationContext的區別

在IDEA中檢視ApplicationContext的繼承關係圖:

這裡寫圖片描述

可以看到,ApplicationContext繼承了BeanFactory,BeanFactory是Spring中比較原始的Factory,它不支援AOP、Web等Spring外掛,而ApplicationContext不僅包含了BeanFactory的所有功能,還支援Spring的各種外掛,還以一種面向框架的方式工作以及對上下文進行分層和實現繼承。

BeanFactory是Spring框架的基礎設施,面向Spring本身;而ApplicationContext面向使用Spring的開發者,相比BeanFactory提供了更多面向實際應用的功能,幾乎所有場合都可以直接使用ApplicationContext而不是底層的BeanFactory。