#Spring生命周期回调说明
如果只是简单的对象初始化,我们可以将其放到构造器中处理;如果是对注入的类或者帮助类做一些初始化处理,可以考虑使用初始化方法。
Spring提供了很多的扩展点,其中就有生命周期回调,我们可以在bean初始化之前做一些处理,在bean销毁之前做一些处理。
#早期Spring生命周期扩展方式
InitializingBean: 允许在bean实例化并且设置好所有的必要属性之后,执行初始化一些处理。 DisposableBean: bean销毁前获得一次回调,做一些处理。
#initMethod和destroyMethod
当初我们使用
标签来配置bean的时候,我们可以通过init-method和destroy-method来指定bean自定义的回调方法。 当使用@Bean注解来配置bean的时候,我们通过 @Bean(initMethod="customInit")
和@Bean(destroyMethod="customDestroy")
来指定bean的自定义回调方法。
#推荐扩展方式
@PostStruct: InitializingBean的替代方案 @PreDestroy:DisposableBean的替代方案
#几种回调方式的顺序 可以看到Spring提供的回调方式有很多种,但是在处理这些回调的时候顺序是怎样的呢,在不看源码之前,我们可以通过实验来看一下执行顺序。
public class BeanOrder implements InitializingBean, DisposableBean{
public void customInit(){
System.out.println("***我是通过配置init-method来实现的初始化方法。");
}
public void customDestroy(){
System.out.println("***我是通过配置destroy-method来实现的初始化方法。");
}
@PostConstruct
public void initMethod(){
System.out.println("***我是加了@PostConstruct注解的init方法。");
}
@PreDestroy
public void destroyMethod(){
System.out.println("***我是加了@PreDestroy注解的destroy方法。");
}
@Override
public void destroy() throws Exception {
System.out.println("***我是实现DisposableBean接口的destroy方法。");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("***我是实现InitializingBean接口的afterPropertiesSet方法。");
}
}
#####执行结果如下:
***我是加了@PostConstruct注解的init方法。
***我是实现InitializingBean接口的afterPropertiesSet方法。
***我是通过配置init-method来实现的初始化方法。
***我是加了@PreDestroy注解的destroy方法。
***我是实现DisposableBean接口的destroy方法。
***我是通过配置destroy-method来实现的初始化方法。
#代码演练 ####InitializingBean
/**
*
* Spring官方已经不推荐这种方式来扩展Bean的初始化操作。
* @author Xiaoyang.Li
*
* https://github.com/superliyang
*/
@Component
public class UseInitializingBean implements InitializingBean{
public void afterPropertiesSet() throws Exception {
System.out.println("实现InitializingBean接口来完成初始化操作,跟@PostConstruct意义一样。");
}
}
####DisposableBean
@Component
public class UseDisposableBean implements DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println("实现DisposableBean接口来实现bean销毁之前做一些操作。");
}
}
当然了,一般很少单独使用DisposableBean,很多时候我们只是单独使用InitializingBean,或者同时使用InitializingBean和DisposableBean 。
####@PostConstruct and PreDestroy
/**
* 生命周期回调(Bean lifecycle callback)
* Bean的生命周期扩展是很重要的,首先要知道,bean在生命周期有哪些地方可以自定义扩展。
* Bean通过@PostConstruct和@PreDestroy来扩展生命周期内的操作。
* 关于使用构造器和初始化方法的分析:如果只是简单的对象初始化,我们可以将其放到构造器中处理;如果是对注入的类或者帮助类做一些初始化处理,可以考虑使用初始化方法。
* @author Xiaoyang.Li (https://github.com/superliyang)
*
*/
@Component
public class BeanLifeCycleExample {
public BeanLifeCycleExample(){
System.out.println("初始化构造器");
}
@PostConstruct
public void initMethod(){
//该方式跟在xml中bean标签上设置init-method是一样的。
//<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
System.out.println("@PostConstruct允许容器bean创建并设置好所有必要属性之后,做出一些初始化处理");
}
@PreDestroy
public void destroyMethod(){
//该方式跟在xml中bean标签上设置destroy-method是一样的。
//<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/>
System.out.println("@PreDestroy允许在bean销毁之前做出一些处理");
}
public void postProcessBeforeInitializationTest(){
System.out.println("在bean实例化完成,调用初始化方法之前,来调用我吧。");
}
}