一、Bean 的生命周期
Bean的生命周期是指:bean创建 --- 初始化 --- 销毁的过程
Spring中是由 IOC 容器管理 bean 的生命周期,我们可以自定义初始化和销毁方法,
容器在 bean 进行到当前生命周期的时候来调用我们自定义初始化方法和销毁方法。
1、构造方法(对象创建)
单实例:在容器启动的时候创建对象;
多实例:每次获取的时候创建对象;
2、初始化方法
单实例:对象创建完成,并赋值好,调用初始化方法。
多实例bean:在创建的时候调用;
3、销毁方法
单实例:容器关闭的时候,销毁对象;
多实例:容器不会管理整个bean,在需要的时候负责创建,容器不会调用销毁方法。
方式一:指定初始化和销毁方法
通过 @Bean 指定 init-method 和 destory-method 方法
方式二:通过让 Bean 实现 InitializingBean(定义初始化逻辑) 和 DisposableBean(定义销毁逻辑) 这两个接口,
然后重写其中的方法。
方式三:使用 JSR250规范中的注解
在方法上使用注解来进行说明。
@PostConstruct:在 bean创建完成并且属性赋值完成,来执行初始化方法,在方法上
@PreDestroy:在容器销毁 bean之前通知我们进行清理工作
使用 BeanPostProcessor bean的后置处理器
postProcessBeforeInitialization:在初始化之前工作
postProcessAfterInitialization:在初始化之后工作
二、方式一:@Bean 注解指定方法
使用 @Bean 注解指定初始化和销毁方法;
原来是在配置文件的 bean 标签中使用 init-method 和 destory-method 来指定方法。
现在可以在配置类中通过 @Bean 注解中的 initMethod 和 destoryMethod 来指定方法:
声明 Car 类:
public class Car {
public Car() {
System.out.println("Car constructor...");
}
public void init() {
System.out.println("Car ... init...");
}
public void destory() {
System.out.println("Car ... destory...");
}
}
配置类:
@Configuration
public class MainConfigOfLifeCycle {
@Bean(initMethod = "init", destroyMethod = "destory")
public Car getCar() {
return new Car();
}
}
测试:
@Test
public void test01() {
AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("IOC容器创建完毕");
ioc.close();
}
三、方式二:实现接口
通过让 Bean 实现 InitializingBean(定义初始化逻辑) 和 DisposableBean(定义销毁逻辑) 这两个接口,然后重写其中的方法。
声明 Cat 类:
public class Cat implements InitializingBean, DisposableBean {
public Cat() {
System.out.println("cat constructor");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("cat ... afterPropertiesSet ...");
}
@Override
public void destroy() throws Exception {
System.out.println("cat ... destory ...");
}
}
配置类:
@Configuration
public class MainConfigOfLifeCycle {
@Bean
public Cat getCat() {
return new Cat();
}
}
四、方式三
使用 JSR250 规范中的注解,在方法上面使用注解来进行说明:
@PostConstruct:在 bean创建完成并且属性赋值完成,来执行初始化方法,在方法上
@PreDestroy:在容器销毁 bean之前通知我们进行清理工作
声明 Dog 类:
public class Dog {
public Dog() {
System.out.println("Dog constructor");
}
//对象创建并赋值之后调用
@PostConstruct
public void init() {
System.out.println("Dog....@PostConstruct。。。");
}
//容器移除对象之前
@PreDestroy
public void destory() {
System.out.println("Dog....@PreDestroy。。。");
}
}
配置类:
@Configuration
public class MainConfigOfLifeCycle {
@Bean
public Dog getDog() {
return new Dog();
}
}
测试:
五、方式四:BeanPostProcessor 后置处理器
使用 BeanPostProcessor bean的后置处理器
postProcessBeforeInitialization:在初始化之前工作
postProcessAfterInitialization:在初始化之后工作
定义 Bean 的后置处理器:
/**
* 后置处理器:初始化前后进行处理工作
* 将后置处理器加入到容器中
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization" + beanName + "=>" + bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization" + beanName + "=>" + bean);
return bean;
}
}
将后置处理器添加到容器中:
@Configuration
public class MainConfigOfLifeCycle {
@Bean
public Dog getDog() {
return new Dog();
}
@Bean
public MyBeanPostProcessor getMyBeanPostProcessor() {
return new MyBeanPostProcessor();
}
}
测试:
六、BeanPostProcessor 原理
源码 DeBug:【AbstractAutowireCapableBeanFactory】
流程:
populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
initializeBean
{
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
遍历得到容器中所有的 BeanPostProcessor;挨个执行 beforeInitialization,
一但返回null,跳出for循环,不会执行后面的 BeanPostProcessor.postProcessorsBeforeInitialization
Spring 底层对 BeanPostProcessor 的使用:
① ApplicationContextAwareProcessor:用于向 bean 组件中添加 ioc 容器;
② BeanValidationPostProcessor:用于数据的校验工作;
③ InitDestroyAnnotationBeanPostProcessor:用于解析 @PostConstruct 和 @PreDestory 注解
④ AutowiredAnnotationBeanPostProcessor:解析 @Autowired 注解,来注入其他组件;
Spring 中提供了一系列的 BeanPostProcessor,可以用于给 bean 赋值,注入其他组件,还有的用来解析 @Autowired 注解,解析生命周期注解功能的多样的 BeanPostProcessor。