1. 程式人生 > >Spring Bean的生命週期 ---附詳細流程圖及測試程式碼

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的生命週期問題已基本解決,不過還等待著你繼續去深入。