1. BeanFactory中Bean的生命周期
- 1.当调用者通过getBean(beanName)向容器请求某个Bean时 如果容器注册了InstantiationAwareBeanPostProcessor接口
在实例Bean之前 将调用接口的postProcessBeforeInstantiation()方法 - 2.根据配置情况调用Bean构造函数或者工厂方实例化Bean
- 3.如果容器注册了InstantiationAwareBeanPostProcessor接口 实例化Bean之后 调用该接口的postProcessAfterInstantiation()方法
- 4.如果Bean设置了属性信息 在这一步将着手配置到bean对应的属性中 不过在设置每个属性之前先调用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues()方法
- 5.调用Bean的属性设置方法设置属性值
- 6.如果Bean实现了BeanNameAware接口 将调用setBeanName()方法 将配置文件中该Bean对应的名称设置到Bean中
【让Bean获得配置文件中对应的配置名称】 - 7.如果Bean实现了BeanFactoryAware接口,将调用setBeanFactory接口方法 将BeanFactory容器实例设置到Bean中
【让接口感知容器】 - 8.如果BeanFactory装配了BeanPostProcessor后处理器 调用BeanPostProcessor的postProcessBeforeInitialization(Object,String)方法对Bean进行加工操作
【为容器提供对Bean进行后续加工处理的切入点 AOP 动态代理都是通过BeanPostProcessor实施的】 - 9.如果Bean实现了InitializingBean的接口 调用afterPropertiesSet()方法
- 10.如果在通过inti-method属性定义了初始化方法 将执行这个方法
- 11.调用BeanPostProcessor后处理器的postProcessAfterInitialization(Object,String)方法 获得对Bean进行再次加工的机会
- 12.如果在中指定Bean的作用范围是scope=’prototype’ 将Bean返回给调用者 调用者负责Bean后续生命的管理
如果作用范围是scope=’singleton’ 将Bean放入Spring IoC容器的缓存池中 并将Bean引用返回给调用者 - 13.对于scope=’singleton’的Bean 当容器关闭时 触发Spring对Bean后续生命周期的管理工作 首先如果Bean首先了DisposableBean接口 则调动接口的afterPropertiesSet()方法 可以在此释放资源记录日志
- 14.调用destory-method中的方法
以上可以大致分为三个部分:
- Bean自身的方法:
调动Bean构造函数实例化Bean 调用setter设置Bean的属性以及通过init-method和destory-method指定的方法 - Bean级生命周期接口方法:
BeanNameAware,BeanFactoryAware,InitializingBean和DisposableBean - 容器级声明周期接口方法:
InstantiationAwareBeanPostProcesor和BeanPostProcessor两个接口实现 一般称他们的实现类为后处理器
验证生命周期的例子:
package life_circle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
/**
* 实现管理Bean生命周期的接口
* Created by heqianqian on 2017/8/9.
*/
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;
}
public String getBrand() {
return brand;
}
public BeanFactory getBeanFactory() {
return beanFactory;
}
public String getBeanName() {
return beanName;
}
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
public void setColor(String color) {
this.color = color;
}
public String getColor() {
return color;
}
public void introduce() {
System.out.println("brand:" + brand
+ " color:" + color + " maxspeed:" + maxSpeed);
}
/**
* BeanFactoryAware中的方法
* 为Bean注入BeanFactory
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("调用BeanFactoryAware中的setBeanFactory方法");
this.beanFactory = beanFactory;
}
/**
* BeanNameAware中的方法
* 将配置文件中设置的Bean的属性注入到Bean中
*/
@Override
public void setBeanName(String s) {
System.out.println("调用BeanNameAware中的setBeanName方法");
this.beanName = s;
}
/**
* DisposableBean接口中的方法 用于销毁Bean
*/
@Override
public void destroy() throws Exception {
System.out.println("调用DisposableBean中的destroy方法");
}
/**
* InitializingBean接口中的方法
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("调用InitializingBean中的afterPropertiesSet方法");
}
/**
* init-method属性中指定的方法
*/
public void myInit(){
System.out.println("调用init-method属性中的方法");
this.maxSpeed = 250;
}
/**
* destroy-method属性中指定的方法
*/
public void myDestroy(){
System.out.println("调用destroy-method属性中的方法");
}
}
package life_circle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* MyBeanPostProcessor
* 后处理器
* Created by heqianqian on 2017/8/9.
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
if (s.equals("car")) {
Car car = (Car) o;
if (car.getColor() == null) {
System.out.println("BeanPostProcessor.postProcessBeforeInitialization,颜色为空 设置为黑色");
car.setColor("Black");
}
}
return o;
}
@Override
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
if (s.equals("car")) {
Car car = (Car) o;
if (car.getMaxSpeed() > 200) {
System.out.println("BeanPostProcessor.postProcessAfterInitialization,速度调整为200");
car.setMaxSpeed(200);
}
}
return o;
}
}
package life_circle;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import java.beans.PropertyDescriptor;
/**
* MyInstantiationAwareBeanPostProcessor
* 自定义实例化Bean处理器
* Created by heqianqian on 2017/8/9.
*/
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
/**
* 在实例化Bean之前调用
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("car".equals(beanName)) {
System.out.println("InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization");
}
return bean;
}
/**
* 在实例化Bean之后调用
*/
@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;
}
}
package life_circle;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import java.io.IOException;
/**
* BeanLifeCycle
* Bean生命周期测试
* Created by heqianqian on 2017/8/9.
*/
public class BeanLifeCycle {
private static void LifeCycleInBeanFactory() {
//装载配置文件 并启动容器
Resource resource = new ClassPathResource("bean_life_factory.xml", BeanLifeCycle.class.getClassLoader());
BeanFactory factory = new XmlBeanFactory(resource);
//向容器中注册MyBeanPostProcessor后处理器
((ConfigurableBeanFactory) factory).addBeanPostProcessor(new MyBeanPostProcessor());
//向容器三种注册MyInstantiationAwareBeanPostProcessor后处理器
((ConfigurableBeanFactory) factory).addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
//第一次从容器中获取Car 触发容器实例化该Bean
Car car1 = (Car) factory.getBean("car");
car1.introduce();
car1.setColor("红色");
//第二次从容器中获取Car 直接从缓存池中获取
Car car2 = (Car) factory.getBean("car");
//查看car1和car2是否指向同一引用
System.out.println("car1==car2:" + (car1 == car2));
//关闭容器
((XmlBeanFactory) factory).destroySingletons();
}
public static void LifeCycleContext() {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean_life_context.xml");
Car car = (Car) ac.getBean("car");
car.introduce();
}
public static void main(String[] args) throws IOException {
LifeCycleInBeanFactory();
}
}
运行结果:
调用Car()构造方法!
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
InstantiationAwareBeanPostProcessor.postProcessPropertyValues
Disconnected from the target VM, address: '127.0.0.1:51018', transport: 'socket'
调用setBrand()设置属性
调用BeanNameAware中的setBeanName方法
调用BeanFactoryAware中的setBeanFactory方法
BeanPostProcessor.postProcessBeforeInitialization,颜色为空 设置为黑色
InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization
调用InitializingBean中的afterPropertiesSet方法
调用init-method属性中的方法
BeanPostProcessor.postProcessAfterInitialization,速度调整为200
brand:BENZ color:Black maxspeed:200
调用Car()构造方法!
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
InstantiationAwareBeanPostProcessor.postProcessPropertyValues
调用setBrand()设置属性
调用BeanNameAware中的setBeanName方法
调用BeanFactoryAware中的setBeanFactory方法
BeanPostProcessor.postProcessBeforeInitialization,颜色为空 设置为黑色
InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization
调用InitializingBean中的afterPropertiesSet方法
调用init-method属性中的方法
BeanPostProcessor.postProcessAfterInitialization,速度调整为200
car1==car2:false
2.ApplicationContext中Bean的生命周期
ApplicationContext中Bean的生命周期和BeanFactory中类似,不同点是如果Bean实现了ApplciationContextAware接口的话 会增加一个调用setApplicationContext()的方法 在postProcessBeforeInialization()方法之后
ApplicationContext和BeanFactory的不同
ApplicationContext和BeanFactory的不同点是
- 1.BeanFactory在初始化容器时 并没有去实例化Bean 直到通过getBean()第一次访问Bean的时候才会对Bean进行初始化
而ApplicationContext在出初始化上下时就实例化所有的单实例Bean - 2.ApplicationContext可以通过反射访问XML配置文件 而BeanFactory不行 因此需要手动的add不同的处理器 而ApplicationContext可以直接在配置文件中配置