本篇文章介绍spring bean 生命周期的各个阶段,包括初始化、和销毁过程。
一、bean 的生命周期
当Spring容器启动时,通过不同的方式实例化完成bean以后,bean将放入容器中进行管理。放入到容器的bean需要执行一系列初始化后,才能使其进行可用的状态。之后,当我们不再需要bean时,bean将会被从容器中移除。
SpringBeanFactory在bean的全生命周期过程中参与管理,起到至关重要的作用。
1.1 启动初始化过程
在容器启动后,SpringBeanFactory
就会开始工作。在整个初始化的过程中,严格意义上来讲,实际上会有三个层级的初始化处理,包括工厂级别的处理(BeanFactoryPostProcessor
等)、容器级别的处理(InstantiationAwareBeanPostProcessor
、BeanPostProcessor
等)、Bean级别的处理(专属某一个bean)。
工厂级别的处理,还有容器级别的处理基本上是Spring框架层面的内容,不做太深入的研究,在代码中引入这些处理,会加深代码对Spring的耦合。不过这篇文章会简单说一下可能会使用到的BeanPostProcessor
。
图上是bean的初始化过程,除开BeanPostProcessor
后置处理器,其它的过程都是Bean级别的初始化处理。
- 初始化开始是java本身的实例化构造对象
- 接着set依赖注入(SDI)
- 再接着通过*Aware接口让bean感知Spring容器资源,比如
beanName
,ApplicationContext
等 - 然后是容器级别的
BeanPostProcessor##PostProcessorBeforeInitialization
bean初始化前置操作 - 接着是执行有注解
@PostConstruct
的方法 - 然后是执行接口
InitializationBean#AfterPropertiesSet
的实现 - 其次是执行
@Bean#initMethod
- 最后是容器级别的
BeanPostProcessor##PostProcessorBeforeInitialization
bean初始化后置操作,至此bean初始化完成
1.2 容器关闭销毁过程
容器执行shutdown
关闭操作后,bean就会开始一系列的销毁操作,相比较初始化操作,销毁步骤少了很多。
- bean销毁开始执行有注解
@Predestory
的方法 - 然后是执行接口
DisposeBean#destory
的实现 - 最后执行
@Bean#destroyMethod
,至此,销毁完成
二、代码示例
下面通过简单的打印示例演示Spring bean的生命周期。
首先创建一个业务bean类,实现接口InitializingBean
, DisposableBean
, ApplicationContextAware
, BeanNameAware
。
``` public class TestBean implements InitializingBean, DisposableBean, ApplicationContextAware, BeanNameAware {
private String name;
public TestBean(String name) {
System.out.println("-------------construct--------------");
this.name = name;
}
public void setName(String name) {
System.out.println("-------------set method--------------");
this.name = name;
}
public String getName() {
return name;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("--------InitializingBean#afterPropertiesSet-----");
}
@Override
public void destroy() throws Exception {
System.out.println("---------DisposableBean#destroy--------------");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("---------BeanNameAware#setApplicationContext----");
}
@Override
public void setBeanName(String s) {
System.out.println("----------ApplicationContextAware#setBeanName----");
}
public void initFromBean(){
System.out.println("----------initFrom@Bean----------");
}
public void destroyFromBean(){
System.out.println("----------destroyFrom@Bean---------------");
}
@PostConstruct
public void customInit()
{
System.out.println("---------@PostConstruct----------");
}
@PreDestroy
public void customDestroy()
{
System.out.println("---------@PreDestroy--------");
}
} ```
然后实现自定义的BeanPostProcessor
``` public class TestBeanProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof TestBean){
System.out.println("------------BeanPostProcessor#postProcessAfterInitialization :" + beanName);
}
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof TestBean){
System.out.println("------------BeanPostProcessor#postProcessBeforeInitialization :" + beanName);
}
return bean;
}
} ```
最后实现一个Spring启动类
``` @SpringBootApplication @Import({ TestBeanProcessor.class }) public class SpringsApplication {
public static void main(String[] args) {
final ConfigurableApplicationContext ctx = SpringApplication.run(SpringsApplication.class, args);
ctx.close();
}
@ConditionalOnMissingBean
@Bean(initMethod = "initFromBean",destroyMethod = "destroyFromBean")
public TestBean testBean(){
return new TestBean("testBean"){{
setName("testName");
}};
}
} ```
启动应用程序,打印结果如下
启动初始化过程
关闭容器销毁过程
三、总结
InitializingBean
和 DisposableBean
不是初始化 和销毁bean 的首选方法,因为它将 bean 类与 spring 容器紧密耦合。更好的方法是在bean 定义中使用init-method
,destroyMethod
属性。
从 Spring 2.5开始,还可以使用注释来指定使用@postconstruct
和@predestroy
介入bean生命周期。
预告下一篇将会讲到BeanPostProcessor
,以及*Aware
。