当前位置 博文首页 > blackball1998的博客:Bean生命周期
有时候我们需要在Bean构造过程中的各个时机,执行一些增强逻辑,这时候Spring为我们提供了多种灵活的构造时的增强方式,这些增强方式组成了Bean生命周期的一部分
在指定一个Bean时,我们可以绑定一个initMethod
,Spring在完成这个Bean的实例化之后,会调用绑定的initMethod
@Data
public class Person {
private int age;
private String name;
public Person(int age, String name) {
System.out.println("执行构造器");
this.age = age;
this.name = name;
}
public void doInit() {
System.out.println("执行初始化方法");
}
}
设置@Bean
的initMethod
属性为初始化方法的方法名
@Configuration
public class MyConfiguration {
@Bean(initMethod = "doInit")
public Person person() {
return new Person(18, "wang");
}
}
可以看到Spring在执行完构造器之后调用了绑定的doInit
方法
destroyMethod
的使用方法和initMethod
是一样的,一个是初始化时调用,一个是销毁时调用
@Data
public class Person {
private int age;
private String name;
public Person(int age, String name) {
System.out.println("执行构造器");
this.age = age;
this.name = name;
}
public void doDestroy() {
System.out.println("执行销毁方法");
}
}
@Configuration
public class MyConfiguration {
@Bean(destroyMethod = "doDestroy")
public Person person() {
return new Person(18, "wang");
}
}
在测试方法结束时,Spring的IOC容器会关闭,当容器关闭时或当我们使用BeanDefinitionRegistryPostProcessor
接口移除一个Bean时,将会调用绑定的销毁方法
Spring提供了一个InitializingBean
接口,我们可以在定义Bean时实现这个接口,并重写afterPropertiesSet
方法
@Data
public class Person implements InitializingBean {
private int age;
private String name;
public Person(int age, String name) {
System.out.println("执行构造器");
this.age = age;
this.name = name;
}
@Override
public void afterPropertiesSet() {
System.out.println("执行afterPropertiesSet");
}
}
测试结果如下
效果跟initMethod
也是一样的,在Bean完成实例化之后执行
有用于初始化的接口,就有用于销毁的接口,可以看到这些Spring提供的方式都是成对出现的
在定义Bean时实现DisposableBean
接口,并重写destroy
方法,可以在Bean销毁的时候调用
@Data
public class Person implements DisposableBean {
private int age;
private String name;
public Person(int age, String name) {
System.out.println("执行构造器");
this.age = age;
this.name = name;
}
@Override
public void destroy() {
System.out.println("执行destroy");
}
}
除了Spring之外,Java也提供了两个注解@PostConstruct
和,Spring底层对这两个注解进行了处理
我们只需要在Bean中的方法上标注@PostConstruct
注解,这个方法将会在Bean构造完成之后执行
@Data
public class Person {
private int age;
private String name;
public Person(int age, String name) {
System.out.println("执行构造器");
this.age = age;
this.name = name;
}
@PostConstruct
public void doPostConstruct() {
System.out.println("执行PostConstruct");
}
}
@PreDestroy
的使用方式跟@PostConstruct
一样,只需要标注在需要在Bean销毁时执行的方法上即可
@Data
public class Person {
private int age;
private String name;
public Person(int age, String name) {
System.out.println("执行构造器");
this.age = age;
this.name = name;
}
@PreDestroy
public void doPerDestroy(){
System.out.println("执行PerDestroy");
}
}
除了以上方式外,Spring还提供了一个后置处理器来增强Bean的初始化,我们可以通过实现BeanPostProcessor
接口来编写我们自定义的后置处理器
@Component
public class MyBeanProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization->" + bean);
System.out.println("postProcessBeforeInitialization->" + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization->" + bean);
System.out.println("postProcessAfterInitialization->" + beanName);
return bean;
}
}
创建一个自定义的组件类,实现BeanPostProcessor
接口,并重写postProcessBeforeInitialization
和postProcessAfterInitialization
方法,这两个方法分别会在Bean的初始化之前和之后执行
注意组件类需要添加@Component
注解,这样组件类才会添加到IOC容器中被Spring获取到来执行
postProcessBeforeInitialization
和postProcessAfterInitialization
方法中,参数列表的bean即为处理的bean对象,beanName为bean的名称。方法返回一个Object对象,我们可以拿到传入的bean对象,返回原来的bean对象,或者对bean进行一些处理,返回处理之后的bean
后置处理器和前面的方式的区别是,他会对每一个Bean都生效,Spring在初始化每一个Bean时,会在IOC容器中寻找每一个后置处理器,包括Spring自带的和我们自定义的,遍历这些处理器执行其中的逻辑
我们在测试中将initMethod
也添加上,方便测试后置处理器中两个方法的执行时机
测试结果如下
可以看到后置处理器确实对每一个Bean都进行了处理,除了我们自己添加的Person对象,还有好多Spring自带的Bean。
Spring会在我们执行初始化方法之前执行postProcessBeforeInitialization
方法,之后执行postProcessAfterInitialization
方法。
另外如果需要增强Bean的构造过程,可以使用InstantiationAwareBeanPostProcessor
这个接口,使用方法大同小异
现在我们把每一种方式都用上,测试他们的执行顺序
Bean的定义
@Data
public class Person implements InitializingBean, DisposableBean {
private int age;
private String name;
public Person(int age, String name) {
System.out.println("执行构造器");
this.age = age;
this.name = name;
}
public void doInit() {
System.out.println("执行初始化方法");
}
public void doDestroy() {
System.out.println("执行销毁方法");
}
@Override
public void afterPropertiesSet() {
System.out.println("执行afterPropertiesSet");
}
@Override
public void destroy() {
System.out.println("执行destroy");
}
@PostConstruct
public void doPostConstruct() {
System.out.println("执行PostConstruct");
}
@PreDestroy
public void doPerDestroy() {
System.out.println("执行PerDestroy");
}
}
后置处理器
@Component
public class MyBeanProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof Person