Spring Bean的生命周期小析(二)
在上一篇文章中我们说了BeanFactory中Bean的生命周期(点击这里查看),在这一篇文章中我们说一下ApplicationContex中Bean的生命周期。ApplicationContext中Bean的生命周期和在BeanFactory中的生命周期大致相同,不同的是多了一个BeanFactoryPostProcessor的接口和ApplicationContextAware接口(这个接口会设置应用上下文即ApplicationContext)。如果配置文件中声明了工厂后处理器接口BeanFactoryPostProcessor的实现类,则应用上下文在装载配置文件之后初始化Bean实例之前将调用这些BeanFactoryPostProcessor对配置信息进行加工处理。Spring框架也提供了多个工厂后处理器如:CustomEditorConfigurer、PropertyPlaceholderConfigurer(解析properties文件)。ApplicationContext和BeanFactory的另一个不同之处是(在上篇文章中我们提到了ApplicationContext和BeanFactory的一个不同):ApplicationContext会利用Java反射机制自动识别出配置文件中定义的BeanPostProcessor、InstantiationAwareBeanPostProcessor和BeanFactoryPostProcessor,并将它们自动注册到应用上下文中;而BeanFactory需要我们手工调用addBeanPostProcessor()方法进行注册.下面我们来看一下ApplicationContext中Bean的生命周期的图示:
下面我们写个程序测试一下:
Bean的生命周期接口和自身的方法以及ApplicationContextAware接口:
package com.zkn.newlearn.spring.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* Created by zkn
* BeanFactoryAware、BeanNameAware、InitializingBean、DisposableBean是Bean级的生命周期接口方法.
*/
public class BeanLifeCycleLearn01 implements BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean,ApplicationContextAware {
/**
* 姓名
*/
private String name;
/**
* BeanFactory
*/
private BeanFactory beanFactory;
private String beanName;
static {
System.out.println("BeanLifeCycleLearn01的静态方法块。。。。");
}
private ApplicationContext applicationContext;
public BeanLifeCycleLearn01() {
System.out.println("---------调用BeanLifeCycleLearn01的构造器实例化---------");
}
/**
* 这是BeanFactoryAware接口方法
* @see BeanFactoryAware
* @param beanFactory
* @throws BeansException
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()");
this.beanFactory = beanFactory;
}
/**
* 这是BeanNameAware接口方法
* @see BeanNameAware
* @param s
*/
@Override
public void setBeanName(String s) {
this.beanName = s;
System.out.println("【BeanNameAware接口】调用BeanNameAware.setBeanName()");
}
/**
* 这是DisposableBean接口方法
* @see DisposableBean
* @throws Exception
*/
@Override
public void destroy() throws Exception {
System.out.println("【DiposibleBean接口】调用DiposibleBean.destory()");
}
/**
* 这是InitializingBean接口方法
* @see InitializingBean
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()");
}
public void setName(String name) {
System.out.println("BeanLifeCycleLearn01调用set方法进行name属性值的设置!");
this.name = name;
}
public void initMethod(){
System.out.println("我是配置文件中的init-method。。。。");
}
public void destoryMethod(){
System.out.println("我是配置文件中的destory-method。。。。");
}
@Override
public String toString() {
return "BeanLifeCycleLearn01{" +
"name='" + name + '\'' +
", beanName='" + beanName + '\'' +
'}';
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
System.out.println("ApplicationContextAware中的setApplicationContext方法。。。。。");
}
}
BeanFactoryPostProcessor的实现类:
package com.zkn.newlearn.spring.lifecycle;
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 zkn
* BeanFactoryPostProcessor:这个在Spring容器的生命周期中只会被调用一次。
*/
public class BeanFactoryPostProcessor01 implements BeanFactoryPostProcessor {
public BeanFactoryPostProcessor01() {
super();
System.out.println("这是BeanFactoryPostProcessor实现类构造器!!");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)
throws BeansException {
System.out.println("BeanFactoryPostProcessor调用postProcessBeanFactory方法");
BeanDefinition bd = arg0.getBeanDefinition("beanLifeCycleLearn01");
bd.getPropertyValues().addPropertyValue("name", "wangwuwu");
}
}
实现容器级的InstantiationAwareBeanPostProcessor接口:
package com.zkn.newlearn.spring.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import java.beans.PropertyDescriptor;
/**
* Created by zkn
* InstantiationAwareBeanPostProcessorAdapter:每个Bean在设置属性的时候都会调用者三个方法,在用的时候要慎重.
*/
public class InstantiationAwareBeanPostProcessor01 extends InstantiationAwareBeanPostProcessorAdapter {
public InstantiationAwareBeanPostProcessor01() {
super();
System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!");
}
/**
* 接口方法、实例化Bean之前调用
* @param beanClass
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInstantiation(Class beanClass,
String beanName) throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法");
return null;
}
/**
* 接口方法、实例化Bean之后调用
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法");
if(bean instanceof BeanLifeCycleLearn01){
((BeanLifeCycleLearn01) bean).setName("我被该名为张四了");
}
return bean;
}
/**
* 接口方法、设置某个属性时调用
* @param pvs
* @param pds
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法");
return pvs;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessAfterInstantiation方法");
return true;
}
}
BeanPostProcessor后置处理器:
package com.zkn.newlearn.spring.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* Created by zkn
* BeanPostProcessor:每个Bean都会调用,用的时候要慎重.
*/
public class BeanPostProcessor01 implements BeanPostProcessor {
public BeanPostProcessor01() {
System.out.println("这是BeanPostProcessor实现类构造器!!");
}
@Override
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!");
return o;
}
@Override
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!");
return o;
}
}
Spring的配置文件:
<?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="beanLifeCycleLearn01" class="com.zkn.newlearn.spring.lifecycle.BeanLifeCycleLearn01"
init-method="initMethod" destroy-method="destoryMethod">
<property name="name" value="zhangsan"/>
</bean>
<bean id="beanPostProcessor01" class="com.zkn.newlearn.spring.lifecycle.BeanPostProcessor01"/>
<bean id="beanFactoryPostProcessor01" class="com.zkn.newlearn.spring.lifecycle.BeanFactoryPostProcessor01"/>
<bean id="instantiationAwareBeanPostProcessor01"
class="com.zkn.newlearn.spring.lifecycle.InstantiationAwareBeanPostProcessor01"/>
</beans>
测试方法:
@Test
public void testBeanLifeCycle(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/zkn/newlearn/spring/lifecycle/beans.xml");
BeanLifeCycleLearn01 beanLifeCycle = (BeanLifeCycleLearn01)applicationContext.getBean("beanLifeCycleLearn01");
System.out.println(beanLifeCycle.toString());
((ClassPathXmlApplicationContext)applicationContext).registerShutdownHook();
}
输出结果为:
输出结果和我们上面画的图是一样的。但是这里需要注意的是我们的Bean实现了ApplicationContextAware这个接口。有的人可能是用另外的一个Bean实现了ApplicationContextAware这个接口,然后输出结果可能和我们上面的图是不一样的,为什么会不一样呢?因为实现ApplicationContextAware接口的Bean和我们定义的业务Bean是一样的,即ApplicationContextAware是一个Bean级的生命周期接口,它不是容器级的生命周期接口!!!在这里我们再做个总结,总结一下Bean的生命周期的执行顺序,先执行容器级的生命周期的接口:BeanFactoryPostProcessor的postProcessBeanFactory方法(这个容器只会执行一次),接着实例化BeanPostProcessor的实现类,实例化InstantiationAwareBeanPostProcessorAdapter的实现类;然后一个Bean被创建的顺序是这样的:执行容器级的生命周期接口:InstantiationAwareBeanPostProcessorAdapter的postProcessBeforeInstantiation方法,再执行Bean的实例化,再执行容器级的生命周期接口:InstantiationAwareBeanPostProcessorAdapter的postProcessAfterInstantiation,再执行容器级的生命周期接口:InstantiationAwareBeanPostProcessorAdapter的postProcessPropertyValues,再接着调用bean自身的setter方法进行属性值的设置,再接着调用Bean级的生命周期接口:BeanNameAware的setBeanName方法,再接着调用Bean级的生命周期接口:BeanFactoryAware的setBeanFactory方法,再接着调用Bean级的生命周期接口:ApplicationContextAware的setApplicationContext方法,再接着调用容器级的生命周期接口:BeanPostProcessor中的postProcessBeforeInitialization方法,再接着调用Bean级的生命周期接口:InitializingBean的afterPropertiesSet方法,再接着调用配置文件中的init-method指定的方法,再接着调用容器级的生命周期接口:BeanPostProcessor中的postProcessAfterInitialization方法,再接着调用容器级的生命周期接口:InstantiationAwareBeanPostProcessor的postProcessAfterInitialization方法,接着执行一些的业务操作,当容器关闭时,先调用Bean级的生命周期接口:DiposibleBean的destory方法,最后调用配置文件中destory-method指定的方法。
参考:
Spring 3.x 企业应用开发实战 陈雄华 林开雄著。