Spring中Bean的生命週期

1、Spring bean 生命週期相關接口
    Spring bean生命週期過程中涉及的相關接口可分爲如下幾類:

    1)、Bean自身的方法:這個包括了Bean本身調用的方法和通過配置文件中<bean>的init-method和destroy-method指定的方法

    2)、Bean級生命週期接口方法:這個包括了BeanNameAware、BeanFactoryAware、ApplicationContextAware、InitializingBean和DiposableBean這些接口的方法

    3)、容器級生命週期接口方法:這個包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 這兩個接口實現,一般稱它們的實現類爲“後處理器”。

    4)、工廠後處理器接口方法:這個包括了BeanFactoryPostProcessor、AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工廠後處理器接口的方法。工廠後處理器也是容器級的。在應用上下文裝配配置文件之後立即調用。

2、生命週期過程接口調用實例驗證

1)、首先是一個簡單的Spring Bean,調用Bean自身的方法和Bean級生命週期接口方法,爲了方便演示,它實現了BeanNameAware、
BeanFactoryAware、ApplicationContextAwareInitializingBean和DiposableBean接口,同時有2個方法,對應配置文件中<bean>的init-method和destroy-method。如下:
package com.xl.springtest;

import org.omg.CORBA.PRIVATE_MEMBER;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * Created by xl on 2016/6/22.
 */
public class Student  implements BeanFactoryAware,BeanNameAware,
InitializingBean,DisposableBean,ApplicationContextAware {

private BeanFactory beanFactory;
    private ApplicationContext applicationContext;
    private String  beanName ;


     private String name ;
     private String address;
     private String Phone;

    public Student() {
        System.out.println("這是Student實現類無參數構造器!!");
}

public Student(String name, String address, String phone) {
this.name = name;
        this.address = address;
Phone = phone;
System.out.println("這是Student實現類 帶參數 構造器!!");
}

public String getAddress() {

return address;
}

public void setAddress(String address) {
        System.out.println("【注入屬性】注入屬性address");
        this.address = address;
}

public String getPhone() {
return Phone;
}

public void setPhone(String phone) {
        System.out.println("【注入屬性】注入屬性phone");
Phone = phone;
}

public String getName() {
return name;
}

public void setName(String name) {
        System.out.println("【注入屬性】注入屬性name");
        this.name = name;
}

/**
     * 這是ApplicationContextAware接口方法
* @param applicationContext
* @throws BeansException
     */
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("ApplicationContextAware 接口 ,setApplicationContext()方法被調用");
        this.applicationContext = applicationContext;
}

/**
     * 這是BeanFactoryAware接口方法
* @param beanFactory
* @throws BeansException
     */
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryAware 接口 ,setBeanFactory()方法被調用");
            this.beanFactory = beanFactory;
}

/**
     *  // 這是BeanNameAware接口方法
* @param name
*/
@Override
public void setBeanName(String name) {
        System.out.println("BeanNameAware 接口 ,setBeanName()方法被調用");
           this.beanName = beanName;
}

/**
     * 這是DisposableBean接口方法
* @throws Exception
     */
@Override
public void destroy() throws Exception {
        System.out.println("DisposableBean 接口 ,destroy()方法被調用");

}

/**
     * 這是InitializingBean接口方法
* @throws Exception
     */
@Override
public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean 接口 ,afterPropertiesSet()方法被調用");

}

/**
     *   通過<bean>的init-method屬性指定的初始化方法
*/
public void myInit() {
          System.out.println("【init-method】調用<bean>的init-method屬性指定的初始化方法");
}

/**
     *  通過<bean>的destroy-method屬性指定的初始化方法
*/
public void myDestory() {
           System.out.println("【destroy-method】調用<bean>的destroy-method屬性指定的初始化方法");
}

@Override
public String toString() {
return "Student{" +
"address='" + address + '\'' +
", Phone='" + Phone + '\'' +
", name='" + name + '\'' +
'}';
}
}
2)、接下來是實現BeanFactoryPostProcessor接口的工廠後置處理器類,如下:
package com.xl.springtest;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

/**
 * Created by xl on 2016/6/22.
 */
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{
public MyBeanFactoryPostProcessor() {
super();
System.out.println("這是MyBeanFactoryPostProcessor實現類構造器!!");
}

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

        System.out.println("BeanFactoryPostProcessor調用postProcessBeanFactory方法");
BeanDefinition bd = beanFactory.getBeanDefinition("student");
bd.getPropertyValues().addPropertyValue("phone","1399999999");

}
}
3)、接下來是實現BeanPostProcessor接口的後置處理器類,如下:
package com.xl.springtest;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;

/**
 * Created by xl on 2016/6/22.
 */
public class MyBeanPostProcessor implements BeanPostProcessor {

public MyBeanPostProcessor() {
        System.out.println("這是MyBeanPostProcessor實現類構造器!!");
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("MyBeanPostProcessor  postProcessBeforeInitialization 方法被調用");
        return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("MyBeanPostProcessor  postProcessAfterInitialization 方法被調用");
        return bean;
}
}
4)、下面是InstantiationAwareBeanPostProcessor 接口實現類,InstantiationAwareBeanPostProcessor 本質是BeanPostProcessor的子接口,一般繼承Spring爲其提供的適配器類InstantiationAwareBeanPostProcessorAdapter來使用它,如下:
package com.xl.springtest;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;

import java.beans.PropertyDescriptor;

/**
 * Created by xl on 2016/6/22.
 */
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {

public MyInstantiationAwareBeanPostProcessor() {
super();
System.out.println("這是MyInstantiationAwareBeanPostProcessorAdapter實現類構造器!!");
}

// 接口方法、實例化Bean之前調用
@Override
public Object postProcessBeforeInstantiation(Class beanClass,
String beanName) throws BeansException {
        System.out.println("MyInstantiationAwareBeanPostProcessor調用postProcessBeforeInstantiation方法");
      return null;
}

// 接口方法、實例化Bean之後調用
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)throws BeansException {
      System.out.println("MyInstantiationAwareBeanPostProcessor調用postProcessAfterInitialization方法");
        return bean;

}
// 接口方法、設置某個屬性時調用
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)throws BeansException {
       System.out.println("InstantiationAwareBeanPostProcessor調用postProcessPropertyValues方法");
            return pvs;
}

}
5)、 Bean配置文件bean-life.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="myBeanPostProcessor" class="com.xl.springtest.MyBeanPostProcessor"/>

       <bean id="myMyInstantiationAwareBeanPostProcessor" class="com.xl.springtest.MyInstantiationAwareBeanPostProcessor"/>

       <bean id="myBeanFactoryPostProcessor" class="com.xl.springtest.MyBeanFactoryPostProcessor"/>

       <bean id="student" class="com.xl.springtest.Student" init-method="myInit" destroy-method="myDestory" >
             <property name="address" value="一路21號"/>
              <property name="name" value="xxl"/>
              <property name="phone" value="1388888888"/>

<!--
              <constructor-arg index="0" value="xxl"/>
              <constructor-arg index="1" value="一路21號"/>
              <constructor-arg index="2" value="1388888888"/>
         -->
</bean>

</beans>

6)、測試應用程序:
public static void main(String args[] ){

    ApplicationContext appContext = new ClassPathXmlApplicationContext("bean-life.xml");

Student student = appContext.getBean("student",Student.class);
System.out.println(student);

System.out.println("現在開始關閉容器!");
((ClassPathXmlApplicationContext)appContext).registerShutdownHook();
}

7)、驗證結果輸出
這是MyBeanFactoryPostProcessor實現類構造器!!
BeanFactoryPostProcessor調用postProcessBeanFactory方法
這是MyBeanPostProcessor實現類構造器!!
這是MyInstantiationAwareBeanPostProcessorAdapter實現類構造器!!
MyInstantiationAwareBeanPostProcessor調用postProcessBeforeInstantiation方法
這是Student實現類無參數構造器!!
InstantiationAwareBeanPostProcessor調用postProcessPropertyValues方法
【注入屬性】注入屬性address
【注入屬性】注入屬性name
【注入屬性】注入屬性phone
BeanNameAware 接口 ,setBeanName()方法被調用
BeanFactoryAware 接口 ,setBeanFactory()方法被調用
ApplicationContextAware 接口 ,setApplicationContext()方法被調用
MyBeanPostProcessor  postProcessBeforeInitialization 方法被調用
InitializingBean 接口 ,afterPropertiesSet()方法被調用
【init-method】調用<bean>的init-method屬性指定的初始化方法
MyBeanPostProcessor  postProcessAfterInitialization 方法被調用
MyInstantiationAwareBeanPostProcessor調用postProcessAfterInitialization方法
Student{address='一路21號', Phone='1399999999', name='xxl'}
現在開始關閉容器!
DisposableBean 接口 ,destroy()方法被調用
【destroy-method】調用<bean>的destroy-method屬性指定的初始化方法
Process finished with exit code 0


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章