bean的生命周期指的是从bean创建到初始化到销毁的全过程。
而在spring容器管理的bean的生命周期也是由spring容器管理。即spring容器帮我们创建bean,初始化以及销毁。前面几篇文章关于spring组件的注册即为多种创建bean的方法,对于初始化和销毁,我们也可以自定义方法,当bean进行到对应的生命周期的时候,spring会帮我们调用我们自定义的初始化或销毁方法。
对于之前xml配置bean的方式来讲,可以通过指定init-method及destroy-method属性来定义bean的初始化及销毁方法
<bean id="student" class="com.xinhua.study.bean.Student" scope="prototype" init-method="init()" destroy-method="destroy()"/>
接下来演示注解方式如何配置bean的初始化及销毁方法。直接在@Bean注解上定义initMethod及destroyMethod的属性值即可。
@Slf4j
public class Teacher {
public Teacher(){
log.info("Teacher类的构造器...");
}
public void init(){
log.info("Teacher类的初始化方法...");
}
public void destroy(){
log.info("Teacher类的销毁方法...");
}
}
@Configuration
public class AnnotationConfigOfLifeCycle {
//在此定义bean的初始化及销毁方法
@Bean(initMethod = "init", destroyMethod = "destroy")
public Teacher teacher() {
return new Teacher();
}
}
3.测试,在src/test/java的com
.xinhua.study.test下创建AnnotationConfigTestOfLifeCycle测试类
@Slf4j
public class AnnotationConfigTestOfLifeCycle {
@Test
public void testInitAndDestroyMethod(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AnnotationConfigOfLifeCycle.class);
}
}
测试方法中,仅仅创建了一下spring容器。先来查看下测试结果:
之前的文章我们提到过,单实例bean在容器创建完成时就已经创建成功,我们可以看到Teacher类的构造器已经被调用,同时初始化方法也已经被调用。也就是在容器创建完成时,单实例的bean已经完成了创建及初始化的操作,那么我们的销毁方法何时调用呢?修改一下测试类中的testInitAndDestroyMethod方法,并调用spring容器的close方法。注意,要想调用spring容器的close方法,就不能将容器类型直接声明为ApplicationContext。
@Test
public void testInitAndDestroyMethod(){
//测试容器的关闭时不能将容器声明为ApplicationContext,因为这个接口本身不包含close方法,只能声明为其实现类
// ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AnnotationConfigOfLifeCycle.class);
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AnnotationConfigOfLifeCycle.class);
log.info("容器创建完成");
applicationContext.close();
}
看一下测试结果:
bean实例的销毁方法是在spring容器关闭时才会调用。
比如数据源的创建。初始化时要赋值驱动、url等很多属性,在销毁时我们需要关闭数据源连接。就可以在自定义的初始化及销毁方法中做这些操作。
初始化方法在bean创建及赋值完成后调用
销毁方法在spring容器关闭时调用
初始化方法获取bean实例时候才会调用
多实例bean的销毁方法不会被spring管理调用,需要自己在适当时候手动调用。
@Slf4j
public class Teacher2 implements InitializingBean, DisposableBean {
public Teacher2(){
log.info("Teacher2 constructor...");
}
@Override
public void destroy() throws Exception {
log.info("Teacher2 destroy...");
}
@Override
public void afterPropertiesSet() throws Exception {
log.info("Teacher2 init...");
}
}
@Bean
public Teacher2 teacher2() {
return new Teacher2();
}
@Slf4j
public class Teacher {
public Teacher(){
log.info("Teacher类的构造器...");
}
@PostConstruct()
public void init(){
log.info("Teacher类的初始化方法...");
}
@PreDestroy
public void destroy(){
log.info("Teacher类的销毁方法...");
}
}
@Bean
public Teacher teacher() {
return new Teacher();
}
BeanPostProcessor是Spring提供的一个组件,点开看下源码:
BeanPostProcessor是一个接口,提供了postProcessBeforeInitialization
以及postProcessAfterInitialization两个方法,主要用于在Bean初始化前后做一些处理工作。
查看注释发现:
1.在com.xinhua.study.bean下创建MyBeanPostProcessor类
@Slf4j
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.info("{}初始化之前执行",beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
log.info("{}初始化之后执行",beanName);
return bean;
}
}
到现在为止,bean的创建到初始化到初始化前后的拦截以及到销毁整个生命周期,我们都可以自己去实现啦~