SpringBoot中的Bean的初始化與銷毀順序解析
我今天學習到SpringBoot里面自定義Bean的初始化與銷毀方法
我先總結一下我學到的四種方法:
方法一:
指定init-method 和 destory-method
方法二:
通過讓 Bean 實現(xiàn) InitializingBean 接口,定義初始化邏輯
DisposableBean 接口,定義銷毀邏輯
方法三:
用 @PostConstruct,在 Bean 創(chuàng)建完成并且賦值完成后,執(zhí)行該注解標注的方法
@PreDestroy,在容器銷毀 Bean 之前,執(zhí)行該注解標注的方法
方法四:
通過讓 Bean 實現(xiàn) BeanPostProcessor 接口,在Bean 初始化前后進行一些處理工作
- postProcessBeforeInitialization: 在初始化之前工作
- postProcessAfterInitialization: 在初始化之后工作
然后我就在想它們的執(zhí)行順序是怎樣的:
嘗試一:
配置類:
//告訴Spring這是一個配置類 @Configuration public class MainConfigOfLifeCycle { //利用 init-method 和 destory-method @Bean(initMethod="initTest", destroyMethod="detoryTest") public Car car() { return new Car(); } //實現(xiàn) InitializingBean , DisposableBean 接口 @Bean public Cat cat() { return new Cat(); } //利用 @PostConstruct ,@PreDestroy @Bean public Dog dog() { return new Dog(); } //實現(xiàn) BeanPostProcessor 接口 @Bean public MyBeanPostProcessor myBeanPostProcessor() { return new MyBeanPostProcessor(); } }
4個 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在銷毀時,調用 public void destroy() throws Exception { // TODO Auto-generated method stub System.out.println(" .. DisposableBean .."); } //該Bean創(chuàng)建完成并且賦值完成后,調用 public void afterPropertiesSet() throws Exception { // TODO Auto-generated method stub System.out.println(" .. InitializingBean .."); } } public class Dog { //對象創(chuàng)建并賦值之后調用 @PostConstruct public void init() { System.out.println(" .. @PostConstruct .. "); } //容器移除對象之前 @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; } }
運行:
public class IOCTest_LifeCycle { @Test public void test01() { // 1. 創(chuàng)建IOC容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class); System.out.println("容器創(chuàng)建完成"); // 關閉容器 applicationContext.close(); } }
執(zhí)行結果:
思考:發(fā)現(xiàn)容器在加載 Bean 時是順序的,因為我在MainConfigOfLifeCycle這個配置類里 @Bean 是順序的,所有不能確定這次結果是否準確。
嘗試二:我把上面四種方法都雜糅到一個類里
配置類:
@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 .. "); } }
運行:
public class IOCTest_LifeCycle { @Test public void test01() { // 1. 創(chuàng)建IOC容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class); System.out.println("容器創(chuàng)建完成"); // 關閉容器 applicationContext.close(); } }
執(zhí)行結果:
總結:
創(chuàng)建:
- Bean 構造函數 ——> @PostConstruct ——> InitializingBean 接口 ——> bean 定義的 init-method——> postProcessBeforeInitialization ——> Bean 初始化完成 ——> postProcessAfterInitialization ——> 容器創(chuàng)建完成
銷毀:
- @PreDestroy ——> DisposableBean 接口 ——> bean 定義的 destoryMethod ——> Bean銷毀
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
mybatis對象List<String> List<Integer>屬性映射方式
這篇文章主要介紹了mybatis對象List<String> List<Integer>屬性映射方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12SpringBoot中的@Conditional?注解的使用
@Conditional是Spring4新提供的注解,它的作用是按照一定的條件進行判斷,滿足條件的才給容器注冊Bean,本文主要介紹了SpringBoot中的@Conditional?注解的使用2024-01-01Springboot利用Aop捕捉注解實現(xiàn)業(yè)務異步執(zhí)行
在開發(fā)過程中,盡量會將比較耗時且并不會影響請求的響應結果的業(yè)務放在異步線程池中進行處理,那么到時什么任務在執(zhí)行的時候會創(chuàng)建單獨的線程進行處理呢?這篇文章主要介紹了Springboot利用Aop捕捉注解實現(xiàn)業(yè)務異步執(zhí)行2023-04-04SpringBoot中實現(xiàn)啟動任務的實現(xiàn)步驟
這篇文章主要介紹了SpringBoot中實現(xiàn)啟動任務的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09java8 stream自定義分組求和并排序的實現(xiàn)
這篇文章主要介紹了java8 stream自定義分組求和并排序的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-01-01