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的規則來進行。