一、Bean生命周期
Spring IOC容器可以管理Bean的生命周期,允許在Bean生命周期的特定點執行定制的任務。
Spring IOC容器對Bean的生命周期進行管理的過程如下:
- 通過構造器或工廠方法創建Bean實例
- 為Bean的屬性設置值和對其它Bean的引用
- 調用Bean的初始化方法
- Bean可以使用了
- 當容器關閉時,調用Bean的銷毀方法
在 Bean 的聲明里設置 init-method 和 destroy-method 屬性, 為 Bean 指定初始化和銷毀方法。
下面通過示例來實現上述的過程:
首先,編寫一個Person類:
public class Person { String name; int age; String sex; public String getName() { return name; } public void setName(String name) { System.out.println("執行name屬性"); this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]"; } public void init() { System.out.println("執行初始化方法!"); } public Person() { System.out.println("執行構造函數"); } public void destory() { System.out.println("執行銷毀方法"); } public void fun() { System.out.println("正在使用bean實例"); } }
配置文件bean-cycle.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"> <bean id="person" class="com.test.Person" init-method="init" destroy-method="destory"> <property name="name" value="xujian"></property> <property name="age" value="23"></property> <property name="sex" value="男"></property> </bean> </beans>
測試函數:
public class Main { public static void main(String[] args) { ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("bean-cycle.xml"); Person person=(Person) ctx.getBean("person");
person.fun(); ctx.close(); } }
運行結果:
從上圖可以看到,首先通過構造函數來創建bean的實例,然后通過setter方法設置屬性,在使用bean實例之前,執行了init初始化方法,使用之后又執行了destroy方法。
二、創建Bean后置處理器
Bean后置處理允許在調用初始化方法前后對Bean進行額外的處理,Bean后置處理器對IOC容器的所有Bean實例逐一處理,而非單一實例。其典型應用是:檢查Bean屬性的正確性或根據特定的標准更改Bean的屬性。
對Bean后置處理器而言,需要實現接口BeanPostProcessor,在初始化方法被調用前后,Spring將把每個Bean實例分別傳遞給上述接口的以下兩個方法:
添加Bean后置處理器后,Spring IOC容器對Bean的生命周期管理的過程為:
- 通過構造器或工廠方法創建 Bean 實例
- 為 Bean 的屬性設置值和對其他 Bean 的引用
- 將 Bean 實例傳遞給 Bean 后置處理器的 postProcessBeforeInitialization 方法
- 調用 Bean 的初始化方法
- 將 Bean 實例傳遞給 Bean 后置處理器的 postProcessAfterInitialization方法
- Bean 可以使用了
- 當容器關閉時, 調用 Bean 的銷毀方法
下面就上面的示例進行修改,首先寫一個MybeanPostProcessor類並實現BeanPostProcessor接口,代碼如下:
public class MybeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessBeforeInitialization"+bean+","+beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessAfterInitialization"+bean+","+beanName); return bean; } }
然后在bean-cycle.xml中添加這個類的配置
再次運行測試函數,結果如下截圖:
三、Bean的作用域
scope用來聲明容器中的對象所應該處的限定場景或者說該對象的存活時間。
1、singleton
標記為擁有singleton的對象定義,在Spring的IOC容器中只存在一個實例,所有對該對象的引用將共享這個實例。該實例從容器啟動,並因為第一次請求而初始化之后,將一直存活到容器退出。
2、prototype
擁有prototype的bean定義,容器在接到該類型對象的請求的時候,會每次都重新生成一個新的對象實例給請求方,雖然這種類型的對象的實例化以及屬性設置等工作都是由容器負責的,但是只要准備完畢,並且對象實例返回給請求方之后,容器就不在擁有當前返回對象的引用。
3、request、session和global session
這三類只適用於Web應用程序,通常是與XmlWebApplicationContext共同使用。
-
- request:XmlWebApplicationContext會為每個http請求創建一個全新的request-processor對象供當前請求使用,當請求結束后,該對象實例的生命周期即告結束。request可以看做是prototype的一種特例,除了應用場景更加具體。
- session:Spring容器會為每個獨立的session創建屬於他們自己的全新的對象實例,與request相比,除了擁有更長的存活時間,其他沒什么差別。
- global session:只在基於portlet的web應用程序中才有意義