1. 程式人生 > >Spring中Bean的生命中期與InitializingBean和DisposableBean介面

Spring中Bean的生命中期與InitializingBean和DisposableBean介面

Spring提供了一些標誌介面,用來改變BeanFactory中的bean的行為。它們包括InitializingBeanDisposableBean實現這些介面將會導致BeanFactory呼叫前一個介面的afterPropertiesSet()方法,呼叫後一個介面destroy()方法,從而使得bean可以在初始化和析構後做一些特定的動作。

在內部,Spring使用BeanPostProcessors 來處理它能找到的標誌介面以及呼叫適當的方法。如果你需要自定義的特性或者其他的Spring沒有提供的生命週期行為,你可以實現自己的 BeanPostProcessor。關於這方面更多的內容可以看這裡:

3.7 “使用BeanPostprocessors定製bean”。

所有的生命週期的標誌介面都在下面敘述。在附錄的一節中,你可以找到相應的圖,展示了Spring如何管理bean;那些生命週期的特性如何改變你的bean的本質特徵以及它們如何被管理。

1. InitializingBean / init-method

實現org.springframework.beans.factory.InitializingBean 介面允許一個bean在它的所有必須的屬性被BeanFactory設定後,來執行初始化的工作。InitializingBean介面僅僅制定了一個方法:

    * Invoked by a BeanFactory after it has set all bean properties supplied    * (and satisfied BeanFactoryAware and ApplicationContextAware).    * <p>This method allows the bean instance to perform initialization only    * possible when all bean properties have been set and to throw an    * exception in the event of misconfiguration.    * @throws Exception in the event of misconfiguration (such    * as failure to set an essential property) or if initialization fails.    */    void afterPropertiesSet() throws Exception;

注意:通常InitializingBean介面的使用是能夠避免的(而且不鼓勵,因為沒有必要把程式碼同Spring耦合起來)。Bean的定義支援指定一個普通的初始化方法。在使用XmlBeanFactory的情況下,可以通過指定init-method屬性來完成。舉例來說,下面的定義:

<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>public class ExampleBean {    public void init() {        // do some initialization work    }}

同下面的完全一樣:

<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>public class AnotherExampleBean implements InitializingBean {    public void afterPropertiesSet() {        // do some initialization work    }}

但卻不把程式碼耦合於Spring

2. DisposableBean / destroy-method

實現org.springframework.beans.factory.DisposableBean介面允許一個bean可以在包含它的BeanFactory銷燬的時候得到一個回撥。DisposableBean也只指定了一個方法:

    /**    * Invoked by a BeanFactory on destruction of a singleton.    * @throws Exception in case of shutdown errors.    * Exceptions will get logged but not rethrown to allow    * other beans to release their resources too.    */    void destroy() throws Exception;

注意:通常DisposableBean介面的使用能夠避免的(而且是不鼓勵的,因為它不必要地將程式碼耦合於Spring)。 Bean的定義支援指定一個普通的析構方法。在使用XmlBeanFactory使用的情況下,它是通過 destroy-method屬性完成。舉例來說,下面的定義:

<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="destroy"/>public class ExampleBean {    public void cleanup() {        // do some destruction work (like closing connection)    }}

同下面的完全一樣:

<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>public class AnotherExampleBean implements DisposableBean {    public void destroy() {        // do some destruction work    }}

但卻不把程式碼耦合於Spring

重要的提示:當以portotype模式部署一個bean的時候,bean的生命週期將會有少許的變化。通過定義,Spring無法管理一個non-singleton/prototype bean的整個生命週期,因為當它建立之後,它被交給客戶端而且容器根本不再留意它了。當說起non-singleton/prototype bean的時候,你可以把Spring的角色想象成“new”操作符的替代品。從那之後的任何生命週期方面的事情都由客戶端來處理。BeanFactorybean的生命週期將會在第 3.4.1 “生命週期介面”一節中有更詳細的敘述 .