bean的生命周期
通常意义上讲的bean的生命周期,指的是bean从创建到初始化,经过一系列的流程,最终销毁的过程。只不过,在Spring中,bean的生命周期是由Spring容器来管理的。在Spring中,我们可以自己来指定bean的初始化和销毁的方法。我们指定了bean的初始化和销毁方法之后,当容器在bean进行到当前生命周期的阶段时,会自动调用我们自定义的初始化和销毁方法。
容器管理bean的生命周期的方法:
- @bean 指定初始化和销毁方法
- 通过让bean实现InitializingBean接口(定义初始化逻辑)和DisposableBean接口(定义销毁逻辑)
- 使用JSR250:@PostConstruct和@PreDestroy
- BeanPostProcessor:bean的后置处理器(重点)
一、@bean 指定初始化和销毁方法
在spring文件中配置bean的时候,是可以配置bean的初始化和销毁方法的。
<bean id="car" class="com.wjh.bean.Car" init-method="init" destroy-method="destory">
</bean>
在注解开发中在@bean注解的属性可以配置初始化和销毁的方法。
定义一个简单的car类。在类中定义初始化和销毁方法。
public class Car {
public void init(){
System.out.println("car...init()...了");
}
public void destory(){
System.out.println("car...destory()...了");
}
}
在配置类中配置bean,并且指定bean的初始化和销毁方法。
/**
* bean的生命周期
*/
@Configuration
public class MainConfigOfLifeCycle {
@Scope("singleton")
@Bean(initMethod = "init",destroyMethod = "destory")
public Car car(){
System.out.println("car实例注入容器中。。。");
return new Car();
}
}
测试:
@Test
public void test7() {
ApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器初始化完成。。");
}
测试结果:
car实例注入容器中。。。
car...init()...了
容器初始化完成。。
在单实例的情况下,容器在注入容器中的时候就执行了初始化方法了。至于销毁方法没有执行,是因为容器没有进行销,需要手动执行销毁方法。
@Test
public void test7() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器初始化完成。。");
context.close();
}
说明:因为在ApplicationContext中没有close()方法,所以需要定义为实现了ApplicationContext 接口的AnnotationConfigApplicationContext类。
结果:
car实例注入容器中。。。
car...init()...了
容器初始化完成。。
car...destory()...了
在多实例的情况下,bean会等到被调用时才会注入容器。
@Configuration
public class MainConfigOfLifeCycle {
@Scope("prototype")
@Bean(initMethod = "init",destroyMethod = "destory")
public Car car(){
System.out.println("car实例注入容器中。。。");
return new Car();
}
}
测试:
@Test
public void test7() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器初始化完成。。");
Object car = context.getBean("car");
System.out.println(car);
context.close();
}
容器初始化完成。。
car实例注入容器中。。。
car...init()...了
com.wjh.bean.Car@4445629
在多实例的情况下,容器不会管理bean实例,所以没有执行销毁方法。
二、InitializingBean接口和DisposableBean接口
InitializingBean和DisposableBean的接口定义了
//实例创建之后执行
void afterPropertiesSet() throws Exception;
//容器销毁之后执行
void destroy() throws Exception;
@Component
public class Car implements InitializingBean, DisposableBean {
public Car() {
System.out.println("car被实例化了。。。");
}
@Override
public void destroy() throws Exception {
System.out.println("car执行了destroy()方法。。。");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("car执行了afterPropertiesSet()方法。。。");
}
}
/**
* bean的生命周期
*/
@Configuration
@ComponentScan("com.wjh")
public class MainConfigOfLifeCycle {
}
测试结果:
car被实例化了。。。
car执行了afterPropertiesSet()方法。。。
容器初始化完成。。
com.wjh.bean.Car@479d31f3
car执行了destroy()方法。。。
三、@PostConstruct和@PreDestroy
@PostConstruct:
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}
@PreDestroy:
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PreDestroy {
}
@PostConstruct和@PreDestroy注解都是可以标注在方法上的,作用:
- @PostConstruct:在bean创建完成并属性赋值完成,来执行初始化方法
- @PreDestroy:在容器销毁bean之前通知我们进行清理工作。
@Component
public class Dog {
public Dog() {
System.out.println("dog...constructor...");
}
@PostConstruct
public void init() {
System.out.println("car...@PostConstruct...init()...了");
}
@PreDestroy
public void destory() {
System.out.println("car...@PreDestroy...destory()...了");
}
}
测试结果:
dog...constructor...
car...@PostConstruct...init()...了
容器初始化完成。。
com.wjh.bean.Dog@43195e57
car...@PreDestroy...destory()...了
四、BeanPostProcessor(重点)
在bean初始化前后进行一些出来工作。在spring和springboot中重点使用。
BeanPostProcessor接口:
//在初始化之前工作
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
//在初始化之后工作
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
创建一个类,并实现BeanPostProcessor接口。
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization..."+beanName+"----->"+beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization..."+beanName+"----->"+beanName);
return bean;
}
}
说明:需要注入到容器中
测试结果:
postProcessBeforeInitialization...mainConfigOfLifeCycle----->mainConfigOfLifeCycle
postProcessAfterInitialization...mainConfigOfLifeCycle----->mainConfigOfLifeCycle
dog...constructor...
postProcessBeforeInitialization...dog----->dog
car...@PostConstruct...init()...了
postProcessAfterInitialization...dog----->dog
说明:在bean的初始化前后工作。