天天看點

Spring之路(14)--bean的生命周期

1. 何為生命周期

所謂生命周期,一個對象(包括普通對象、Spring容器、Spring普通bean)從生存到毀滅的全過程。

2. 何為作用域

由Spring容器建立的bean的生存期,被稱為bean的作用域,也就是bean有作用生存期。

常見的作用域有四周:

singleton作用域,針對一個bean定義隻建立一個bean執行個體,在Spring容器整個生命周期都可以使用該執行個體。注意這也是bean的預設作用域。前面我們示範的bean都是這一類。

prototype作用域,這種類似于java中使用new建立的對象,每次從容器中取出時,都會建立一個全新的bean。

request作用域,每一個Web請求都會建立一個新的bean執行個體,該作用域隻能在Web應用程式中使用。

session作用域,針對不同的會話建立新的bean執行個體,該作用域隻能在Web應用程式中使用。

簡單的了解,singleton作用域時,無論從容器中取出多少次,都是取出的一個對象,該對象一直存活,知道容器關閉;prototype作用域時,每次從容器中取出,都是取出一個全新的bean。而request作用域和session作用域需要我們了解web程式中一次請求和一次會話的概念。

3. 四種作用域具體文法

在xml情況下,使用scope="xxx"指定bean的作用域

<bean id="singer" class="org.maoge.Singer" scope="singleton"><bean>

1

在注解情況下,使用@Scope(“xxx”)指定bean的作用域

@Component

@Scope("singleton")

public class Singer{

}

在JavaConfig下,也是使用@Scope(“xxx”)指定bean的作用域

4. 延遲初始化及其作用

有時候我們的程式會有很多bean,有些bean啟動速度比較慢(例如需要通路資料庫的、需要通路網絡加載資源的、需要通路本地檔案加載資訊的)。

而這些啟動速度慢的bean,有可能在程式剛啟動時、或者啟動一段時間内不會被使用。這樣我們可以讓這些bean延遲啟動以便提高程式啟動的速度。

我在項目中就遇到過,有一些bean是netty相關的網絡子產品bean,加載速度很慢且非常浪費系統性能,而且實際上有可能并不會被用到(有些客戶會使用,有些客戶并不會用到),如果上來就加載這些bean,無疑會大大拖慢系統啟動速度,配置延遲初始化後,情況大大改觀。

注意預設情況下,Spring容器在啟動階段就建立bean了,延遲初始化是真正需要bean時才予以建立。

在使用xml配置bean時,延遲初始化文法如下:

<bean id="singer" class="org.maoge.Singer" lazy-init="true"></bean>

在使用注解配置bean時,延遲初始化文法如下:

@Lazy(true)

在JavaConfig下,也是使用@Lazy(true)設定bean為延遲初始化

5. 指定bean先後加載順序

有時候需要指定bean的加載順序,例如一個bean中有資料庫通路相關邏輯并完成了資料庫接口的初始化工作,另一個bean需要調用bean通路資料庫,則我們需要保證第一個bean加載完了,再加載第二個bean。

此時可以是喲好難過depends-on文法,bean2 depends-on bean1表示bean2依賴于bean1,是以此時容器會先加載bean1。

xml下具體文法為:

<bean id="bean2" class="org.maoge.test.Bean2" depends-on="bean1"></bean>

同樣可以用使用@DependsOn注解表示相同含義。

6. bean的建立與銷毀回調

如果一個bean封裝了jdbc資料通路邏輯,則我們應該在其注入url、user、password等屬性後,進行資料庫連接配接的初始化,并在該bean銷毀之前關閉資料庫連接配接。

此時我們就需要用到bean建立成功後的回調方法,與bean銷毀前的回調方法。

在xml中,具體文法如下:

<bean id="datasource" class="org.maoge.test.db" init-method="initDatasource" destroy-method="destroyDataSource"></bean>

在使用注解時,文法如下:

public class DataSource{

 @PostConstruct//bean建立成功後回調該方法

 public void init throws Exception(){

 }

 @PreDestroy//bean銷毀之前回調該方法

 public void destroy throws Exception(){

7. 總結

普通java對象的生命周期管理,是由我們自行建立的,并且由垃圾回收器負責收回。

Spring架構中的bean對象,整個生命周期都是由Spring進行管理的,是以如果要對其生命周期進行設定、管理,需要使用Spring的規則來進行。