本文分析下bean的生命周期,spring bean从创建到初始化,在到销毁的过程。其中初始化的过程中,spring又为我们留了几个接口,方便我们实现一些特殊的效果。
1 生命周期整体流程
bean的生命周期总结为3大步骤:
- 实例化
- 初始化
- 销毁
1.1 实例化
前面文章中spring5源码阅读(三)的最后一节,我们分析过,创建bean发生在AbstractAutowireCapableBeanFactory#doCreateBean方法中;实例化和初始化都发生在这里。
实例化本节不着重讲述,我们主要分析下面的初始化过程。
1.2 初始化
初始化发生在AbstractAutowireCapableBeanFactory#doCreateBean的如下一行代码:
exposedObject = initializeBean(beanName, exposedObject, mbd);
初始化过程中相关的接口(注解)有:
- BeanNameAware#setBeanName
- BeanFactoryAware#setBeanFactory
- ApplicationContextAware#setApplicationContext
- BeanPostProcessor#postProcessBeforeInitialization
- @PostConstruct
- InitializingBean#afterPropertiesSet
- 自定义initMethod方法,通过@Bean或者Xml配置
- BeanPostProcessor#postProcessAfterInitialization
执行顺序:从上到下。
从后边的demo中可以验证。
1.3 销毁
bean的销毁发生在annotationConfigApplicationContext.close();过程中。
销毁过程中相关的接口(注解)有:
- @PreDestroy
- DisposableBean#destroy()
- 自定义destroyMethod
执行顺序:从上到下。
从后边的demo中可以验证。
2 Demo演示
这里我们主要说初始化和销毁过程中相关的接口。
还是从第一篇文章spring5源码阅读(一)中的demo开始。
重新写一下:
public static void main(String[] args) {
//这里完成了代理 target---proxy
AnnotationConfigApplicationContext annotationConfigApplicationContext =
new AnnotationConfigApplicationContext(Appconfig.class);
annotationConfigApplicationContext.close();
}
我们在写一个类MyLifeCyc:
public class MyLifeCyc implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {
@Override
public void setBeanName(String name) {
System.out.println(this.getClass().getSimpleName() + "调用BeanNameAware接口的setBeanName方法");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println(this.getClass().getSimpleName() + "调用BeanFactoryAware接口的setBeanFactory方法");
}
@PostConstruct
public void postConstruct() {
System.out.println(this.getClass().getSimpleName() + "调用自定义postConstruct方法");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println(this.getClass().getSimpleName() + "调用ApplicationContextAware接口的setApplicationContext方法");
}
public void myInit() {
System.out.println(this.getClass().getSimpleName() + "调用自定义myInit方法");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(this.getClass().getSimpleName() + "调用InitializingBean接口的afterPropertiesSet方法");
}
@Override
public void destroy() throws Exception {
System.out.println(this.getClass().getSimpleName() + "调用DisposableBean接口的DisposableBean方法");
}
public void myDestroy() throws Exception {
System.out.println(this.getClass().getSimpleName() + "调用自定义的myDestroy方法");
}
@PreDestroy
public void preDestroy() throws Exception {
System.out.println(this.getClass().getSimpleName() + "调用自定义的preDestroy方法");
}
}
再给MyLifeCyc类增加个初始化myInit和销毁方法myDestroy:
@Configuration
@ComponentScan("com.test")
@EnableAspectJAutoProxy
public class Appconfig {
@Bean(initMethod = "myInit", destroyMethod = "myDestroy")
MyLifeCyc myLifeCyc() {
return new MyLifeCyc();
}
}
执行main方法,有如下输出:
MyLifeCyc调用BeanNameAware接口的setBeanName方法
MyLifeCyc调用BeanFactoryAware接口的setBeanFactory方法
MyLifeCyc调用ApplicationContextAware接口的setApplicationContext方法
MyLifeCyc调用自定义postConstruct方法
MyLifeCyc调用InitializingBean接口的afterPropertiesSet方法
MyLifeCyc调用自定义myInit方法
MyLifeCyc调用自定义的preDestroy方法
MyLifeCyc调用DisposableBean接口的destroy方法
MyLifeCyc调用自定义的myDestroy方法
这里还漏了一点,就是BeanPostProcessor接口;这个接口比较特别的是,它对每个bean都是会发挥作用的,
我们在写一个类MyBeanPostProcessorImpl:
@Service
public class MyBeanPostProcessorImpl implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(bean.getClass().getSimpleName() + "对象" + beanName + "开始初始化");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(bean.getClass().getSimpleName() + "对象" + beanName + "初始化完成");
return bean;
}
}
假设我们的项目中还有类A/B/C,那么MyBeanPostProcessorImpl会作用于这3个类,包括上面的MyLifeCyc类。
此时再次执行main方法,输出:
MyLifeCyc调用BeanNameAware接口的setBeanName方法
MyLifeCyc调用BeanFactoryAware接口的setBeanFactory方法
MyLifeCyc调用ApplicationContextAware接口的setApplicationContext方法
MyLifeCyc对象myLifeCyc开始初始化
MyLifeCyc调用自定义postConstruct方法
MyLifeCyc调用InitializingBean接口的afterPropertiesSet方法
MyLifeCyc调用自定义myInit方法
MyLifeCyc对象myLifeCyc初始化完成
MyLifeCyc调用自定义的preDestroy方法
MyLifeCyc调用DisposableBean接口的destroy方法
MyLifeCyc调用自定义的myDestroy方法