1、借用一张ApplicationContext中bean的生命周期流程图:
2、ApplicationContext bean生命周期涉及组件说明:
在BeanFactory的bean生命周期中的组件在ApplicationContext中的bean生命周期中也都存在,除此之外ApplicationContext bean生命周期涉及组件还多出了几个,我们主要介绍多出来的几个组件。
2.1、BeanFactoryPostProcessor:bean工厂后置处理器。
主要职责:就是在ApplicationContext的beanFactory 这个bean 实例准备就绪后,就会调用所有实现了BeanFactoryPostProcessor接口的类的 postProcessBeanFactory()方法,在这里我们可以随意修改一些bean的BeanDefinition,这就是“偷天换日”,每个实现类的postProcessBeanFactory()方法在整个ApplicationContext加载中只会执行一次(区分BeanPostProcessor)。
2.2、ApplicationContextAware:应用上下文感知器。
主要职责:给需要知道自己所处ApplicationContext 的bean 调用setApplicationContext()方法。
2.3、@PostConstruct:定义初始化bean之前操作的注解。
主要职责:定义bean初始化之前需要做的操作,标注在方法上面表示bean初始化之前调用此方法。
2.4、@PreDestroy:定义注销bean之前操作的注解。
主要职责:定义bean销毁之前需要做的操作,标注在方法上面表示bean销毁之前调用此方法。
3、ApplicationContext中bean生命周期流程:
1、调用所有实现了BeanFactoryPostProcessor接口的类的 postProcessBeanFactory()方法。
2、调用添加的所有InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()方法。
3、实例化bean。
4、调用添加的所有InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()方法。
5、调用添加的所有InstantiationAwareBeanPostProcessor.postProcessPropertyValues()方法。
6、如果bean实现了BeanNameAware接口,调用bean的setBeanName()函数。
7、如果bean实现了BeanFactoryAware接口,调用bean的setBeanFactory()函数。
8、如果bean实现看ApplicationContextAware接口,调用bean的setApplicationContext()方法。
9、调用添加的所有BeanPostProcessor.postProcessBeforeInitialization()方法。
10、调用bean中 @PostConstruct注解函数的处理。
11、如果bean实现了InitializingBean接口,调用bean的afterPropertiesSet()方法。
12、如果<bean/>上定义的init-method 属性,则调用bean中的init-method属性值的方法。
13、调用添加的所有BeanPostProcessor.postProcessAfterInitialization()方法。
销毁bean触发如下:
14、调用bean中 @PreDestroy注解函数的处理。
15、如果bean实现了DisposableBean接口,则调用bean中的destroy()方法。
16、如果<bean/>上定义的destroy-method 属性,则调用bean中的destroy-method属性值的方法。
4、ApplicationContext中bean生命周期流程测试 :
测试代码:
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-context.xml");
Bar bar = (Bar) ac.getBean("bar");
((ClassPathXmlApplicationContext) ac).destroy();
测试结果:
BeanFactoryPostProcessor.postProcessBeanFactory。。。 整个上下文只会触发一次
InstantiationAwareBeanPostProcessor 的 before。。。 每个bean生命周期中都会触发一次
Construct... 每个bean生命周期中都会触发一次
InstantiationAwareBeanPostProcessor 的 after。。。 每个bean生命周期中都会触发一次
InstantiationAwareBeanPostProcessor 的 postProcessPropertyValues。。。 每个bean生命期中都会触发一次
BeanPostProcessor 的 before。。。 每个bean生命周期中都会触发一次
@PostConstruct注解。。。 bean如果配置了则生命周期中都会触发一次
InitializingBean 的afterPropertiesSet。。。 bean如果配置了则生命周期中都会触发一次
<bean/> init-method 属性。。。 bean如果配置了则生命周期中都会触发一次
BeanPostProcessor 的 after。。。 每个bean生命周期中都会触发一次
@PreDestroy注解。。。 bean如果配置了则生命周期中都会触发一次
DisposableBean 的 destroy。。。 bean如果配置了则生命周期中都会触发一次
<bean/> destroy-method 属性。。。 bean如果配置了则生命周期中都会触发一次
5、BeanFactory与 ApplicationContext生命周期的区别
1、BeanFactory 生命周期中InstantiationAwareBeanPostProcessor、BeanPostProcessor等处理器需要手动调用BeanFactory.addBeanPostProcessor()方法将其注册到BeanFactory中,而ApplicationContext中的BeanFactoryPostProcessor、InstantiationAwareBeanPostProcessor、BeanPostProcessor等后置处理器只需要定义BeanDefinition, ApplicationContext会根据反射自动将其注册到ApplicationContext的BeanFactory中。
2、BeanFactory 中只有在调用BeanFactory.getBean()方法才会开始bena的生命周期,这就是所谓的spring “第一次惩罚”的问题,而ApplicationContext 在加载的过程中就会将开始bean的生命周期,底层也是使用ApplicationContext 的BeanFactory.getBean()函数来将除了延迟加载的所有bena的生命周期走完,解决了“第一次惩罚”的问题,也解决了在加载的时候就将bean配置如果存在的错误,提前暴露出来。
3、ApplicationContext 中bean的生命周期多了4个组件,一是BeanFactoryPostProcessor,其实从理论上来说BeanFactoryPostProcessor这个应该是BeanFactory 工厂实例的生命周期组件。二是ApplicationContextAware 接口。三是@PostConstruct 注解。四是@PreDestroy注解。
6、案例中使用的代码:
public class Bar implements InitializingBean,DisposableBean {
private String price;
public Bar() {
System.out.println("Construct...");
}
public String getPrice() {return price;}
public void setPrice(String price) {this.price = price;}
@PostConstruct
public void intit(){
System.out.println("@PostConstruct注解。。。");
}
@PreDestroy
public void preDestroy(){
System.out.println("@PreDestroy注解。。。");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean 的 destroy。。。");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean 的afterPropertiesSet。。。");
}
public void myinit(){
System.out.println("<bean/> init-method 属性。。。");
}
public void mydestroy(){
System.out.println("<bean/> destroy-method 属性。。。");
}
}
自定义BeanFactoryPostProcessor
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(
ConfigurableListableBeanFactory configurableListableBeanFactory)
throws BeansException {
System.out.println("BeanFactoryPostProcessor.postProcessBeanFactory。。。" +
"整个bean工厂 只执行一次。。。BeanFactoryPostProcessor");
BeanDefinition bar = configurableListableBeanFactory.getBeanDefinition("bar");
bar.getPropertyValues().add("price", "234");
}
}
自定义InstantiationAwareBeanPostProcessor
@Component
public class MyInstantiationAwareBeanPostProcessor extends
InstantiationAwareBeanPostProcessorAdapter {
@Override
public Object postProcessBeforeInstantiation(Class <?> aClass,
String s) throws BeansException {
if (s.equals("bar")){
System.out.println("InstantiationAwareBeanPostProcessor 的 before。。。");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object o,
String s)
throws BeansException {
if (s.equals("bar")){
System.out.println("InstantiationAwareBeanPostProcessor 的 after。。。");
}
return true;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues propertyValues,
PropertyDescriptor[]
propertyDescriptors,
Object o,
String s) throws BeansException {
if (s.equals("bar")){
System.out.println("InstantiationAwareBeanPostProcessor 的
postProcessPropertyValues。。。");
}
return propertyValues;
}
}
自定义BeanPostProcessor
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object o,
String s)
throws BeansException {
if (s.equals("bar")){
System.out.println("BeanPostProcessor 的 before。。。");
}
return o;
}
@Override
public Object postProcessAfterInitialization(Object o,
String s)
throws BeansException {
if (s.equals("bar")){
System.out.println("BeanPostProcessor 的 after。。。");
}
return o;
}
}