SpringBoot中的Bean的初始化與銷毀順序解析
我今天學習到SpringBoot裡面自定義Bean的初始化與銷毀方法
我先總結一下我學到的四種方法:
方法一:
指定init-method 和 destory-method
方法二:
通過讓 Bean 實現 InitializingBean 接口,定義初始化邏輯
DisposableBean 接口,定義銷毀邏輯
方法三:
用 @PostConstruct,在 Bean 創建完成並且賦值完成後,執行該註解標註的方法
@PreDestroy,在容器銷毀 Bean 之前,執行該註解標註的方法
方法四:
通過讓 Bean 實現 BeanPostProcessor 接口,在Bean 初始化前後進行一些處理工作
- postProcessBeforeInitialization: 在初始化之前工作
- postProcessAfterInitialization: 在初始化之後工作
然後我就在想它們的執行順序是怎樣的:
嘗試一:
配置類:
//告訴Spring這是一個配置類 @Configuration public class MainConfigOfLifeCycle { //利用 init-method 和 destory-method @Bean(initMethod="initTest", destroyMethod="detoryTest") public Car car() { return new Car(); } //實現 InitializingBean , DisposableBean 接口 @Bean public Cat cat() { return new Cat(); } //利用 @PostConstruct ,@PreDestroy @Bean public Dog dog() { return new Dog(); } //實現 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創建完成並且賦值完成後,調用 public void afterPropertiesSet() throws Exception { // TODO Auto-generated method stub System.out.println(" .. InitializingBean .."); } } public class Dog { //對象創建並賦值之後調用 @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. 創建IOC容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class); System.out.println("容器創建完成"); // 關閉容器 applicationContext.close(); } }
執行結果:
思考:發現容器在加載 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 創建"); } 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. 創建IOC容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class); System.out.println("容器創建完成"); // 關閉容器 applicationContext.close(); } }
執行結果:
總結:
創建:
- Bean 構造函數 ——> @PostConstruct ——> InitializingBean 接口 ——> bean 定義的 init-method——> postProcessBeforeInitialization ——> Bean 初始化完成 ——> postProcessAfterInitialization ——> 容器創建完成
銷毀:
- @PreDestroy ——> DisposableBean 接口 ——> bean 定義的 destoryMethod ——> Bean銷毀
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Java Spring Bean的生命周期管理詳解
- 使用spring容器在初始化Bean時前和後的操作
- 深入瞭解Spring的Bean生命周期
- Spring源碼解析之BeanPostProcessor知識總結
- 詳解Spring中Bean後置處理器(BeanPostProcessor)的使用