BeanFactory中的Bean的生命周期
在这里直接通过例子分析Bean的整个生命周期。
例子
package Car;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class Car implements BeanFactoryAware, BeanNameAware,InitializingBean,DisposableBean{
private String brand;
private String color;
private int maxSpeed;
private BeanFactory beanFactory;
private String beanName;
public Car(){
System.out.println("调用Car()构造方法。");
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
System.out.println("调用SetBrand()方法");
this.brand = brand;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
public Car(String brand,String color,int maxSpeed){
this.brand = brand;
this.color = color;
this.maxSpeed = maxSpeed;
}
public void introduce(){
System.out.println("brand:"+brand+";color:"+color+";maxSpeed:"+maxSpeed);
}
//BeanFactoryAware接口方法
public void setBeanFactory(BeanFactory beanFactory) throws BeansException{
System.out.println("调用BeanFactoryAware.setBeanFactory()");
this.beanFactory=beanFactory;
}
//BeanNameAware接口方法
public void setBeanName(String beanName){
System.out.println("调用BeanNameAware.setBeanName()");
this.beanName=beanName;
}
//InitializingBean接口方法
public void afterPropertiesSet() throws Exception{
System.out.println("调用InitializingBean.afterPropertiesSet()");
}
//DisposableBean接口方法
public void destroy() throws Exception{
System.out.println("调用DisposableBean.destroy()");
}
//通过<bean>的init-method属性指定初始化方法
public void myInit(){
System.out.println("调用初始化方法,maxSpeed为240.");
}
//通过<bean>的destroy-method属性指定销毁方法
public void myDestroy(){
System.out.println("调用销毁方法.");
}
}
这里实现各种生命周期控制访问的Car,Car类实现了BeanFactoryAware, BeanNameAware,InitializingBean,DisposableBean这些Bean级的生命周期控制接口,同时定义了myInit()和myDestroy()方法,以便在配置文件中通过的init-method属性指定初始化方法与destroy-method属性指定销毁方法。
package BeanFactoryLifeCycle;
import java.beans.PropertyDescriptor;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter{
//接口方法,在实例化之前调用
public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException{
//对容器中Bean进行处理
if("car".equals(beanName)){
System.out.println("InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation");
}
return null;
}
//接口方法,在实例化之后调用
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException{
//对容器中Bean进行处理
if("car".equals(beanName)){
System.out.println("InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation");
}
return true;
}
//接口方法,在设置某个属性时调用
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds,Object bean, String beanName) throws BeansException{
//仅对容器中Bean进行某个特定属性处理,还可以通过pdst入参进行过滤
if("car".equals(beanName)){
System.out.println("InstantiationAwareBeanPostProcessor.postProcessPropertyValues");
}
return pvs;
}
}
MyInstantiationAwareBeanPostProcessor通过扩展InstantiationAwareBeanPostProcessor适配器InstantiationAwareBeanPostProcessorAdapter提供实现。在MyInstantiationAwareBeanPostProcessor中,通过过滤条件仅对car Bean进行处理,而对其他Bean一概不做处理。
此外,提供了一个BeanPostProcessor实现类,在该实现类中,只对car Bean进行处理,对配置文件所提供的属性设置值进行判断,做到补缺补漏。
package BeanFactoryLifeCycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import Car.Car;
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if(beanName.equals("car")){
Car car = (Car)bean;
if(car.getMaxSpeed()>=200){
System.out.println("调用BeanPostProcessor.postProcessBeforeInitialization(),maxSpeed为200");
car.setMaxSpeed(199);
}
}
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
if(beanName.equals("car")){
Car car = (Car)bean;
if(car.getColor()==null){
System.out.println("调用BeanPostProcessor.postProcessAfterInitialization(),color为空,设置默认为黑色");
car.setColor("黑色");
}
}
return bean;
}
}
在MyBeanPostProcessor中postProcessAfterInitialization()、postProcessBeforeInitialization()这两个方法便是对我们所设置的bean进行查缺补漏,若触发条件,便会进行处理。
package BeanFactoryLifeCycle;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import Car.Car;
public class BeanLifeCycle {
private static void LifeCycleInBeanFactory(){
Resource res = new ClassPathResource("BeanFactoryLifeCycle/beans.xml");
BeanFactory bf = new XmlBeanFactory(res);
//向容器中注册MyBeanPostProcessor和MyInstantiationAwareBeanPostProcessor后处理器
((ConfigurableBeanFactory)bf).addBeanPostProcessor(new MyBeanPostProcessor());
((ConfigurableBeanFactory)bf).addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
Car car1 = (Car)bf.getBean("car");
car1.introduce();
car1.setColor("红色");
Car car2 = (Car)bf.getBean("car");
System.out.println("car1==car2:"+(car1==car2));
((XmlBeanFactory)bf).destroySingletons();
}
public static void main(String[] args) {
LifeCycleInBeanFactory();
}
}
装载了配置文件并启动容器并且向容器中注册MyBeanPostProcessor和MyInstantiationAwareBeanPostProcessor后处理器。后处理器的实际调用顺序与注册顺序是无关的,在具有多个后处理器的情况下,可通过org.springframework.core.Ordered接口以确定调用顺序。
配置文件:
运行结果:
从整个运行结果看出,通过getBean()调用某个Bean后调用了InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法→实例化→InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法→
InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法→设置属性值→调用BeanNameAware的setBeanName()方法→调用BeanFactoryAware的setBeanFactory()方法→调用BeanPostProcessor的postProcessBeforeInitialization()方法→调用InitializingBean的afterPropertiesSet()方法→通过init-method属性配置的初始化方法→调用BeanPostProcessor的postProcessAfterInitialization()方法→【singleton】Spring缓存池中准备就绪的Bean→调用DisposableBean的destroy()方法→通过destroy-method属性配置的销毁方法。
如果Bean的作用范围定义为scope=“prototype”,则第二次getBean()时,生命周期方法会再次调用,因为prototype范围的Bean每次都返回新的实例。
ApplicationContext中的Bean的生命周期
Bean在应用上下文的生命周期与BeanFactory中生命周期类似,不同的是,如果Bean实现了org.springframework.context.ApplicationContextAware接口会增加一个调用该接口方法setApplicationContext()的步骤。
此步骤加在BeanFactoryAware.setBeanFactory()→调用BeanPostProcessor.postProcessBeforeInitialization()之间。工厂后处理器是容器级的,仅在应用上下文初始化时调用一次,其目的是完成一些配置文件的加工处理工作。
ApplicationContext和BeanFactory另一个最大的不同之处在于,前者会利用Java反射机制自动识别出配置文件中定义的InstantiationAwareBeanPostProcessor、BeanPostProcessor、BeanFactoryPostProcessor,并自动将它们注册到上下文中,而后者需要在代码中通过手工调用addBeanPostProcessor()方法进行注册。