bean的生命週期——Spring對bean的管理(三)
本章案例基於上節,看不懂的請先看上節——bean的作用域:
https://blog.csdn.net/qq_34598667/article/details/83269250
bean的生命週期
1、bean的例項化:bean在何時被例項化?
2、bean的初始化:init-method:指定初始化回撥方法,在例項化 bean 時,立即呼叫該方法
3、bean的銷燬:destroy-method:銷燬回撥方法,只有從容器中移除 bean 之後,才能呼叫該方法。
4、預設的初始化和銷燬方法
beans標籤內部 default-init-method=“init” default-destroy-method=“destroy”
bean在何時被例項化?
大家已經學過servlet的生命週期了,servlet是被web容器進行管理的,而servlet的例項化有兩種方式:web容器在載入時和servlet被訪問時。與servlet類似,bean是被spring容器所管理的,所以bean的例項化無外乎兩種情況:
1、Spring容器啟動時。
2、呼叫getBean()方法時。
這裡我們要注意的是,bean的例項化時間跟Bean的作用域也有一定的關係,我們以上節內容spring bean的作用域為基礎舉例
1)當bean的作用域為singleton時
修改Demo類,新增構造方法:
public class Demo {
public Demo(){
System.out.println("正在例項化...");
}
private String name;
}
然後修改spring.xml的配置檔案如下,使用scope的預設值:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 構造器例項化 -->
<bean id="demo" class="com.oak.junit.day01.Demo"></bean>
</beans>
即bean的作用域為singleton時,我們修改測試類的程式碼,新增測試方法為:
@Test
public void testLife(){
//例項化Spring容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
}
控制檯輸出:
正在例項化...
說明了當bean的作用域為singleton時,bean物件是在Spring容器啟動時就進行建立了。即預設情況下會在容器啟動時初始化bean。
我們也可以指定bean的初始化時機為在呼叫getBean()方法時被初始化,使用bean元素的lazy-init屬性:
lazy-init:true,延遲初始化的 bean 告訴 Ioc 容器在它第一次被請求時,而不是在啟動時去建立一個 bean 例項。
修改bean節點程式碼為:
<!-- 構造器例項化 -->
<bean id="demo" class="com.oak.junit.day01.Demo" scope="prototype"
lazy-init="true"></bean>
直接測試發現並沒有任何輸出,更改測試方法為:
@Test
public void testLife(){
//例項化Spring容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
Demo demo=ctx.getBean("demo",Demo.class);
}
重新測試發現控制檯輸出:
正在例項化...
則說明了lazy-init=”true”指定了不要在Spring容器啟動時對這個bean進行例項化。
如果想對所有bean都應用延遲初始化,可以在根節點beans設定default-lazy-init=“true”,程式碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-lazy-init="true">
......
</beans>
2)當bean的作用域為prototype時
修改spring.xml配置檔案,刪除bean節點的lazy-init=”true”,程式碼如下:
<!-- 構造器例項化 -->
<bean id="demo" class="com.oak.junit.day01.Demo" scope="prototype"></bean>
增加測試方法如下:
@Test
public void testLifePrototype(){
//例項化Spring容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
}
進行測試發現沒有任何輸出,修改測試方法,增加getBean()方法的呼叫
@Test
public void testLifePrototype(){
//例項化Spring容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
Demo demo=ctx.getBean("demo",Demo.class);
}
控制檯輸出:
正在例項化...
說明當bean的作用域為prototype時,bean物件並不會在Spring容器啟動時就進行建立。 bean物件將會在呼叫getBean()方法時進行建立。
bean的初始化
我們希望在bean被初始化的時候,就初始化某些資源。為了達到這樣的目的,我們可以給類新增初始化方法:
public class Demo {
//定義初始化方法
public void init(){
System.out.println("正在被初始化...");
}
public Demo(){
System.out.println("正在例項化...");
}
private String name;
}
在Spring.xml中為bean指定初始化方法,使用bean元素的init-method屬性:
<!-- 構造器例項化 -->
<bean id="demo" class="com.oak.junit.day01.Demo" lazy-init="false" init-method="init"></bean>
執行測試方法:
@Test
public void testInit(){
//例項化Spring容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
}
控制檯輸出:
正在例項化...
正在初始化...
bean的銷燬
現在我們又希望在bean被銷燬的時候,就釋放或關閉某些資源。為了達到這樣的目的,我們可以給類新增指定的銷燬方法:
public class Demo {
//初始化方法
public void init(){
System.out.println("正在初始化...");
}
public Demo(){
System.out.println("正在例項化...");
}
//銷燬方法
public void destroy() {
System.out.println("釋放初始化的資源");
}
private String name;
}
在Spring.xml中為bean指定初始化方法,使用bean元素的init-method屬性:
<!-- 構造器例項化 -->
<bean id="demo" class="com.oak.junit.day01.Demo" lazy-init="false" init-method="init" destroy-method="destroy"></bean>
新增測試方法並執行:
@Test
public void testDestory(){
//例項化Spring容器
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
//正常關閉Spring容器
ctx.close();
}
控制檯輸出:
正在例項化...
正在初始化...
釋放初始化的資源
PS:bean銷燬的時機
bean到底是什麼時候銷燬的呢?如果沒有人為地刪除它,預設該bean一直在Spring容器中, 也就是說隨著Spring容器的關閉,該bean才會被銷燬。
預設的初始化和銷燬方法
在beans標籤內部新增 default-init-method=“init” default-destroy-method=“destroy”
修改spring.xml程式碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-init-method="init"
default-destroy-method="destroy">
<!-- 構造器例項化 -->
<bean id="demo" class="com.oak.junit.day01.Demo" lazy-init="false"></bean>
</beans>
新增測試方法:
@Test
public void testLife(){
//例項化Spring容器
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
ctx.close();
}
控制檯輸出:
正在例項化...
正在初始化...
釋放初始化的資源
下一章:IOC