BeanFactory接口的生命周期

/ Spring / 没有评论 / 388浏览

我们知道Web容器中的Servlet拥有生命周期,那么同样spring框架中的IOC容器也同样拥有生命周期。并且在IOC容器中对象的生命周期是分多个阶段的,且IOC容器允许每个阶段都可以外界对它进行控制,满足我们开发的所有需求。下面我们简单了解一下BeanFactory接口生命周期的详细过程。

  1. 当我们调用BeanFactory接口中的getBean方法时,如果IOC容器注册了InstantiationAwareBeanPostProcessor接口,则在实例化对象之前,先调用该接口的postProcessBeforeInstantiation方法。
  2. 根据配置信息调用对象构造方法或工厂方法实例化对象。
  3. 如果IOC容器注册了InstantiationAwareBeanPostProcessor接口,则在实例化对象后,调用接口的postProcessAfterInstantiation方法。如果我们想对IOC容器实例化的对象做一些修改,就可以在这个方法中处理。
  4. 如果对象配置了属性信息,IOC容器将在此时为对象设置属性值。但在设置每个属性之前都会先调用InstantiationAwareBeanPostProcessor接口中的postProcessPropertyValues方法。
  5. 调用对象的属性设置方法设置属性值。
  6. 如果对象实现了BeanNameAware接口,则将调用setBeanName方法,将配置文件中对象的名称设置到对象中。
  7. 如果对象实现了BeanFactoryAware接口,则将调用setBeanFactory方法,将BeanFactory容器实例设置到对象中。
  8. 如果BeanFactory装配了BeanPostProcessor处理器,则此时将调用postProcessBeforeInitialization方法对对象进行处理。如果我们想改变对象的行为,可以在此处添加相应逻辑。BeanPostProcessor接口在spring中有很重要的地位,因为它为IOC容器提供了对对象后续加工处理的切入点,spring框架中的AOP、动态代理等技术都是通过BeanPostProcessor实现的。
  9. 如果对象实现了InitializingBean接口,则此时将调用该接口的afterPropertiesSet方法。
  10. 如果对象在配置文件中设置了init-method属性定义了初始化方法,则此时将调用对象已设置的方法。
  11. 如果BeanFactory装配了BeanPostProcessor处理器,则此时将调用该接口的postProcessAfterInitialization方法对对象进行在一次处理。
  12. 如果对象在配置文件中设置了scope="prototype",则spring将当前对象的手续生命周期返回给调用者,spring将不在管理这个对象的生命周期。如果将配置文件中的scope="singleton",则spring会把当前对象放到IOC容器的缓存池中,并继续管理这个对象的舍命周期。
  13. 如果配置文件中设置了scope="singleton",当IOC容器关闭时,如果对象实现了DisposableBean接口,则此时将调用该接口中的destroy方法。
  14. 当配置文件中设置了destroy-method属性指定销毁方法时,spring在此时执行该方法,完成对象的资源释放等操作。

下面我们将通过测试用例的方式,来证明我们上述我说的生命周期的过程。

public class MarkInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if("car".equals(beanName)) {
System.out.println("instantiationAwareBeanPostProcessor.postProcessBeforeInstantiation");
}
return null;
}

@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if("car".equals(beanName)) {
System.out.println("instantiationAwareBeanPostProcessor.postProcessAfterInstantiation");
}
return true;
}

@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
if("car".equals(beanName)) {
System.out.println("instantiationAwareBeanPostProcessor.postProcessPropertyValues");
}
return pvs;
}
}
public class MarkBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
if ("car".equals(s)) {
System.out.println("BeanPostProcessor.postProcessBeforeInitialization");
}
return o;
}

public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
if ("car".equals(s)) {
System.out.println("BeanPostProcessor.postProcessAfterInitialization");
}
return o;
}
}
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 void setBrand(String brand) {
System.out.println("setBrand");
this.brand = brand;
}

@Override
public String toString() {
return "Car{" +
"brand='" + brand + '\'' +
", color='" + color + '\'' +
", maxSpeed=" + maxSpeed +
'}';
}

public String getBrand() {
return 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 void carInit() {
System.out.println("car.carInit");
}

public void carDestroy() {
System.out.println("car.carDestroy");
}

public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryAware.setBeanFactory");
this.beanFactory = beanFactory;
}

public void setBeanName(String s) {
System.out.println("BeanNameAware.setBeanName");
this.beanName = s;
}

public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean.afterPropertiesSet");
}

public void destroy() throws Exception {
System.out.println("DisposableBean.destroy");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="car" class="com.jilinwula.spring.Car" init-method="carInit" destroy-method="carDestroy" p:brand="蔚领" p:maxSpeed="100" scope="singleton"/>

</beans>
/**
* BeanFactory测试
*
* @throws Exception
*/
@Test
public void beanFactory () {
// 启动IOC容器
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("test.xml"));

// 向IOC容器中注册MarkBeanPostProcessor处理器
((ConfigurableBeanFactory) beanFactory).addBeanPostProcessor(new MarkBeanPostProcessor());

// 向IOC容器中注册MarkInstantiationAwareBeanPostProcessor处理器
((ConfigurableBeanFactory) beanFactory).addBeanPostProcessor(new MarkInstantiationAwareBeanPostProcessor());

// 第一次获取car对象
Car car1 = beanFactory.getBean("car", Car.class);
System.out.println(car1);
car1.setColor("白色");

// 第二次获取car对象 验证IOC容器缓存功能
Car car2 = beanFactory.getBean("car", Car.class);

System.out.println(String.format("car1==car2:%s", car1 == car2));
((XmlBeanFactory) beanFactory).destroySingletons();
}
instantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
Car
instantiationAwareBeanPostProcessor.postProcessAfterInstantiation
instantiationAwareBeanPostProcessor.postProcessPropertyValues
setBrand
BeanNameAware.setBeanName
BeanFactoryAware.setBeanFactory
BeanPostProcessor.postProcessBeforeInitialization
InitializingBean.afterPropertiesSet
car.carInit
BeanPostProcessor.postProcessAfterInitialization
Car{brand='蔚领', color='null', maxSpeed=100}
car1==car2:true
DisposableBean.destroy
car.carDestroy