Spring Bean 加载的执行顺序 InitializingBean 接口 @PostConstruct 注解 执行顺序 DisposableBean 接口 @PreDestroy 注解 执行顺序
一、概述
在Spring框架中,bean在加载、销毁时,都可以执行特定的方法,来实现某些功能的增强、信息的记录。
bean在加载完成后,可以通过 InitializingBean 接口 、 @PostConstruct 注解 、@Bean 注解的 initMethod 方法 ,这三种方式 实现相关功能的增强。
bean在销毁时,可以通过 DisposableBean 接口、 @PreDestroy 注解 、@Bean 注解的 destroyMethod 方法 ,这三种方式 实现销毁前的回调,如:线程池资源关闭。
那么问题来了: bean在加载、销毁时,这三种方法的执行顺序是如何呢?本文将以代码的形式,记录验证过程。
二、代码理解
1、理解 bean 加载 和 InitializingBean 接口方法执行顺序
@Component
public class Animal {
public Animal(){
System.out.println("Animal 构造方法运行~");
}
@Bean
public InitializingBean initializingBean(){
return ()->{
System.out.println("Animal initializingBean 方法执行 ~~");
};
}
}
1.1、输出结果:
Animal 构造方法运行~
Animal initializingBean 方法执行 ~~
1.2、结论:构造方法先执行 ; initializingBean 方法后执行
2、比较 @PostConstruct 注解 / InitializingBean 接口 /@Bean 注解的 initMethod 方法 执行顺序
public class BeanStart implements InitializingBean {
public void hehe(){
System.out.println("hehe method ===>> @Bean 注解的 initMethod "+this);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet method ===>> InitializingBean 接口方法");
}
@PostConstruct
public void haha(){
System.out.println("haha method ===>> @PostConstruct 注解" + this);
}
public BeanStart(){
System.out.println("BeanStart 实例化完成后 ===>>> ");
}
}
2.1、输出结果:
BeanStart 实例化完成后 ===>>>
haha method ===>> @PostConstruct 注解com.runcode.springboottourist.bean.BeanStart@7d44a19
afterPropertiesSet method ===>> InitializingBean 接口方法
hehe method ===>> @Bean 注解的 initMethod com.runcode.springboottourist.bean.BeanStart@7d44a19
2.2、结论:@PostConstruct 注解最先执行 、 InitializingBean 接口方法 次之 、 @Bean 注解的 initMethod 方法最后执行
3、比较 @PreDestroy 注解 / DisposableBean 接口 /@Bean 注解的 destroyMethod 方法 执行顺序
public class BeanDestory implements DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println(" DisposableBean 接口的 destroy 方法执行 ~");
}
@PreDestroy
public void overHaHa(){
System.out.println("@PreDestroy 注解 方法执行 ~ overHaHa");
}
public void beanDestory(){
System.out.println("@Bean 注解的 destroyMethod 方法执行 ~ beanDestory");
}
}
3.1、输出结果:
@Bean 注解的 destroyMethod 方法执行 ~ beanDestory
@PreDestroy 注解 方法执行 ~ overHaHa
DisposableBean 接口的 destroy 方法执行 ~
3.2、结论:@PreDestroy 注解 最先执行 、DisposableBean 接口 次之 、 @Bean 注解的 destroyMethod 方法 最后执行
4、上面的2个类:BeanStart 和 BeanDestory ,需要放一个配置类中,如下:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Description: BeanConfig
* @author wu
* @version 1.0
* @date 2022/9/19 23:04
*/
@Configuration
public class BeanConfig {
/**
* @Description: 演示bean初始化后,执行顺序
* @return com.runcode.springboottourist.bean.BeanStart
* @version v1.0
* @author wu
* @date 2022/9/19 23:09
*/
@Bean(initMethod = "hehe")
public BeanStart beanStart(){
return new BeanStart();
}
/**
* @Description: 演示 Bean销毁时,执行顺序
* @return com.runcode.springboottourist.bean.BeanDestory
* @version v1.0
* @author wu
* @date 2022/9/19 23:05
*/
@Bean(destroyMethod = "beanDestory")
public BeanDestory beanDestory(){
return new BeanDestory();
}
}
三、总结
1、类初始化过程中:构造方法 > initializingBean 接口
2、类初始化先后顺序:@PostConstruct > InitializingBean > @Bean
3、类销毁时先手顺序:@PreDestroy > DisposableBean > @Bean
4、@PostConstruct 包路径是:javax.annotation.PostConstruct ; @PreDestroy 包路径是: javax.annotation.PreDestroy ;
5、理解记忆:Java 注解 > Spring 接口 > Spring 注解
Java 注解: @PostConstruct / @PreDestroy
Spring 接口: InitializingBean / DisposableBean
Spring 注解: @Bean (initMethod / destroyMethod)