SpringBoot中的Bean的初始化與銷毀順序解析
我今天學(xué)習(xí)到SpringBoot里面自定義Bean的初始化與銷毀方法
我先總結(jié)一下我學(xué)到的四種方法:
方法一:
指定init-method 和 destory-method
方法二:
通過(guò)讓 Bean 實(shí)現(xiàn) InitializingBean 接口,定義初始化邏輯
DisposableBean 接口,定義銷毀邏輯
方法三:
用 @PostConstruct,在 Bean 創(chuàng)建完成并且賦值完成后,執(zhí)行該注解標(biāo)注的方法
@PreDestroy,在容器銷毀 Bean 之前,執(zhí)行該注解標(biāo)注的方法
方法四:
通過(guò)讓 Bean 實(shí)現(xiàn) BeanPostProcessor 接口,在Bean 初始化前后進(jìn)行一些處理工作
- postProcessBeforeInitialization: 在初始化之前工作
- postProcessAfterInitialization: 在初始化之后工作
然后我就在想它們的執(zhí)行順序是怎樣的:
嘗試一:
配置類:
//告訴Spring這是一個(gè)配置類
@Configuration
public class MainConfigOfLifeCycle {
//利用 init-method 和 destory-method
@Bean(initMethod="initTest", destroyMethod="detoryTest")
public Car car() {
return new Car();
}
//實(shí)現(xiàn) InitializingBean , DisposableBean 接口
@Bean
public Cat cat() {
return new Cat();
}
//利用 @PostConstruct ,@PreDestroy
@Bean
public Dog dog() {
return new Dog();
}
//實(shí)現(xiàn) BeanPostProcessor 接口
@Bean
public MyBeanPostProcessor myBeanPostProcessor() {
return new MyBeanPostProcessor();
}
}
4個(gè) bean:
public class Car{
public void initTest() {
System.out.println(" .. init-method .. ");
}
public void detoryTest() {
System.out.println(" .. destory-method .. ");
}
}
public class Cat implements InitializingBean, DisposableBean {
//該Bean在銷毀時(shí),調(diào)用
public void destroy() throws Exception {
// TODO Auto-generated method stub
System.out.println(" .. DisposableBean ..");
}
//該Bean創(chuàng)建完成并且賦值完成后,調(diào)用
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
System.out.println(" .. InitializingBean ..");
}
}
public class Dog {
//對(duì)象創(chuàng)建并賦值之后調(diào)用
@PostConstruct
public void init() {
System.out.println(" .. @PostConstruct .. ");
}
//容器移除對(duì)象之前
@PreDestroy
public void detory() {
System.out.println(" .. @PreDestroy .. ");
}
}
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println(" .. postProcessBeforeInitialization .. ");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println(" .. postProcessBeforeInitialization .. ");
return bean;
}
}
運(yùn)行:
public class IOCTest_LifeCycle {
@Test
public void test01() {
// 1. 創(chuàng)建IOC容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器創(chuàng)建完成");
// 關(guān)閉容器
applicationContext.close();
}
}
執(zhí)行結(jié)果:

思考:發(fā)現(xiàn)容器在加載 Bean 時(shí)是順序的,因?yàn)槲以贛ainConfigOfLifeCycle這個(gè)配置類里 @Bean 是順序的,所有不能確定這次結(jié)果是否準(zhǔn)確。
嘗試二:我把上面四種方法都雜糅到一個(gè)類里
配置類:
@Configuration
public class MainConfigOfLifeCycle {
@Bean(initMethod="initTest", destroyMethod="detoryTest")
public Car car() {
return new Car();
}
}
Bean:
public class Car implements InitializingBean, DisposableBean, BeanPostProcessor {
public Car() {
System.out.println("Car 創(chuàng)建");
}
public void initTest() {
System.out.println(" .. init-method .. ");
}
public void detoryTest() {
System.out.println(" .. destory-method .. ");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(" .. InitializingBean .. ");
}
@Override
public void destroy() throws Exception {
System.out.println(" .. DisposableBean .. ");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(" .. postProcessBeforeInitialization .. ");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(" .. postProcessAfterInitialization .. ");
return bean;
}
@PostConstruct
public void postConstructTest() {
System.out.println(" .. @PostConstruct .. ");
}
@PreDestroy
public void preDestroyTest() {
System.out.println(" .. @PreDestroy .. ");
}
}
運(yùn)行:
public class IOCTest_LifeCycle {
@Test
public void test01() {
// 1. 創(chuàng)建IOC容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器創(chuàng)建完成");
// 關(guān)閉容器
applicationContext.close();
}
}
執(zhí)行結(jié)果:

總結(jié):
創(chuàng)建:
- Bean 構(gòu)造函數(shù) ——> @PostConstruct ——> InitializingBean 接口 ——> bean 定義的 init-method——> postProcessBeforeInitialization ——> Bean 初始化完成 ——> postProcessAfterInitialization ——> 容器創(chuàng)建完成
銷毀:
- @PreDestroy ——> DisposableBean 接口 ——> bean 定義的 destoryMethod ——> Bean銷毀
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于Lambda表達(dá)式的方法引用和構(gòu)造器引用簡(jiǎn)的單示例
這篇文章主要介紹了關(guān)于Lambda表達(dá)式的方法引用和構(gòu)造器引用簡(jiǎn)的單示例,方法引用與構(gòu)造器引用可以使?Lambda?表達(dá)式的代碼塊更加簡(jiǎn)潔<BR>,需要的朋友可以參考下2023-04-04
SpringBoot整合ES多個(gè)精確值查詢 terms功能實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot整合ES多個(gè)精確值查詢 terms功能實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-06-06
Java JFinal框架中實(shí)現(xiàn)添加定時(shí)任務(wù)功能詳解
這篇文章主要為大家詳細(xì)介紹了如何在JFinal框架項(xiàng)目中添加定時(shí)任務(wù)的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-02-02
SpringBoot中的響應(yīng)式web應(yīng)用詳解
這篇文章主要介紹了SpringBoot中的響應(yīng)式web應(yīng)用詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
關(guān)于Java鎖性能提高(鎖升級(jí))機(jī)制的總結(jié)
這篇文章主要介紹了關(guān)于Java鎖性能提高(鎖升級(jí))機(jī)制的總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
Java簡(jiǎn)單實(shí)現(xiàn)約瑟夫環(huán)算法示例
這篇文章主要介紹了Java簡(jiǎn)單實(shí)現(xiàn)約瑟夫環(huán)算法,簡(jiǎn)單描述了約瑟夫環(huán)問(wèn)題,并結(jié)合實(shí)例形式分析了Java實(shí)現(xiàn)約瑟夫環(huán)的具體操作技巧,需要的朋友可以參考下2017-09-09
深入學(xué)習(xí)Spring Boot排查 @Transactional 引起的 NullPointerException問(wèn)題
這篇文章主要介紹了深入學(xué)習(xí)Spring Boot排查 @Transactional 引起的 NullPointerException問(wèn)題,需要的朋友可以參考下2018-01-01
SpringBoot實(shí)現(xiàn)發(fā)送短信的示例代碼
這篇文章主要介紹了SpringBoot實(shí)現(xiàn)發(fā)送短信的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04

