Spring Bean的生命週期 ---附詳細流程圖及測試程式碼
一、生命週期流程圖:
Spring Bean的完整生命週期從建立Spring容器開始,直到最終Spring容器銷燬Bean,這其中包含了一系列關鍵點
假設一個Bean實現了所有的介面,大的概況一下Bean的生命週期:
1.例項化BeanFactoryPostProcessor:處理的物件是BeanFactory級別
2.例項化BeanPostProcessor實現類
3.例項化InstantiationAwareBeanPostProcessorAdapter實現類,注:該類是BeanPostProcessor的擴充套件
4.執行InstantiationAwareBeanPostProcessorAdapter類的postProcessBeforeInstantiation方法
5.Bean的構造方法
6.執行InstantiationAwareBeanPostProcessorAdapter類的postProcessPropertyValues
7.為Bean注入屬性,即依賴注入
8.呼叫BeanNameAware的setBeanName方法
9.呼叫BeanNameAware的setBeanFactory方法
10.執行BeanPostProcessor的後置處理器,postProcessAfterInitialization方法
11.呼叫InitializingBean的afterPropertiesSet方法
12.呼叫bean的init-method初始化方法
13.執行BeanPostProcessor的postProcessAfterInitialization
14.執行InstantiationAwareBeanPostProcessorAdapter的後置方法,postProcessAfterInitialization
15.Bean的使用
16.呼叫DiposibleBean的destory方法
17.呼叫bean指定的destory-method方法
為了上述流程的正確性,我們可以用程式碼來測試一下:
測試Bean - StudentBean類:
/** * 測試生命週期的Bean * Created by kxm */ public class StudentBean implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware { private String name; private int age; private String beanName; //實現了BeanNameAware介面,Spring可以將BeanName注入該屬性中 private BeanFactory beanFactory; //實現了BeanFactory介面,Spring可將BeanFactory注入該屬性中 public StudentBean(){ System.out.println("【Bean構造方法】學生類的無參構造方法"); } @Override public String toString() { return "StudentBean{" + "name='" + name + '\'' + ", age=" + age + ", beanName='" + beanName + '\'' + '}'; } public String getName() { return name; } public void setName(String name) { System.out.println("【set注入】注入學生的name屬性"); this.name = name; } public int getAge() { return age; } public void setAge(int age) { System.out.println("【set注入】注入學生的age屬性"); this.age = age; } /** * 自己編寫的初始化方法 */ public void myInit(){ System.out.println("【init-method】呼叫init-method屬性配置的初始化方法"); } /** * 自己編寫的銷燬方法 */ public void myDestroy(){ System.out.println("【destroy-method】呼叫destroy-method屬性配置的銷燬方法"); } /** * BeanFactoryAware介面的方法 * @param beanFactory * @throws BeansException */ public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; System.out.println("【BeanFactoryAware介面】呼叫BeanFactoryAware的setBeanFactory方法得到beanFactory引用"); } /** * BeanNameAware介面的方法 * @param name */ public void setBeanName(String name) { this.beanName = name; System.out.println("【BeanNameAware介面】呼叫BeanNameAware的setBeanName方法得到Bean的名稱"); } /** * InitializingBean介面的方法 * @throws Exception */ public void afterPropertiesSet() throws Exception { System.out.println("【InitializingBean介面】呼叫InitializingBean介面的afterPropertiesSet方法"); } /** * DisposableBean介面的方法 * @throws Exception */ public void destroy() throws Exception { System.out.println("【DisposableBean介面】呼叫DisposableBean介面的destroy方法"); } }
MyBeanFactoryPostProcessor工廠處理器類:
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public MyBeanFactoryPostProcessor() {
System.out.println("【BeanFactoryPostProcessor介面】呼叫BeanFactoryPostProcessor實現類構造方法");
}
/**
* 重寫BeanFactoryPostProcessor介面的postProcessBeanFactory方法,可通過該方法對beanFactory進行設定
*/
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
System.out.println("【BeanFactoryPostProcessor介面】呼叫BeanFactoryPostProcessor介面的postProcessBeanFactory方法");
}
}
MyInstantiationAwareBeanPostProcessor類:
/**
* 一般情況下,當我們需要實現InstantiationAwareBeanPostProcessor介面時,是通過繼承Spring框架中InstantiationAwareBeanPostProcessor介面實現類
* InstantiationAwareBeanPostProcessorAdapter這個介面卡類來簡化我們實現介面的工作
*/
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
public MyInstantiationAwareBeanPostProcessor() {
System.out.println("【InstantiationAwareBeanPostProcessor介面】呼叫InstantiationAwareBeanPostProcessor構造方法");
}
/**
* 例項化Bean之前呼叫
*/
public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
System.out.println("【InstantiationAwareBeanPostProcessor介面】呼叫InstantiationAwareBeanPostProcessor介面的postProcessBeforeInstantiation方法");
return null;
}
/**
* 例項化Bean之後呼叫
*/
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("【InstantiationAwareBeanPostProcessor介面】呼叫InstantiationAwareBeanPostProcessor介面的postProcessAfterInitialization方法");
return bean;
}
/**
* 設定某個屬性時呼叫
*/
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
System.out.println("【InstantiationAwareBeanPostProcessor介面】呼叫InstantiationAwareBeanPostProcessor介面的postProcessPropertyValues方法");
return pvs;
}
}
MyBeanPostProcessor類:
/**
* Created by kxm
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor(){
System.out.println("【BeanPostProcessor介面】呼叫BeanPostProcessor的構造方法");
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("【BeanPostProcessor介面】呼叫postProcessBeforeInitialization方法,這裡可對"+beanName+"的屬性進行更改。");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("【BeanPostProcessor介面】呼叫postProcessAfterInitialization方法,這裡可對"+beanName+"的屬性進行更改。");
return bean;
}
}
XML配置:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<!-- 生命週期測試 -->
<!--配置Bean的後置處理器-->
<bean id="beanPostProcessor" class="com.my.spring.life.MyBeanPostProcessor">
</bean>
<!--配置instantiationAwareBeanPostProcessor-->
<bean id="instantiationAwareBeanPostProcessor" class="com.my.spring.life.MyInstantiationAwareBeanPostProcessor">
</bean>
<!--配置BeanFactory的後置處理器-->
<bean id="beanFactoryPostProcessor" class="com.my.spring.life.MyBeanFactoryPostProcessor">
</bean>
<bean id="studentBean" class="com.my.spring.life.StudentBean" init-method="myInit"
destroy-method="myDestroy" scope="singleton">
<property name="name" value="yanxiao"></property>
<property name="age" value="21"></property>
</bean>
</beans>
測試類:
public class TestCyclelife {
/**
* Created by yanxiao on 2016/8/1.
*/
public static void main(String[] args){
System.out.println("--------------【初始化容器】---------------");
ApplicationContext context = new ClassPathXmlApplicationContext("Springlife.xml");
System.out.println("-------------------【容器初始化成功】------------------");
//得到studentBean,並顯示其資訊
StudentBean studentBean = context.getBean("studentBean",StudentBean.class);
System.out.println(studentBean);
System.out.println("--------------------【銷燬容器】----------------------");
((ClassPathXmlApplicationContext)context).registerShutdownHook();
}
}
測試結果如下:
符合上述的Bean的生命週期,至此,Bean的生命週期問題已基本解決,不過還等待著你繼續去深入。