您好,登錄后才能下訂單哦!
今天小編給大家分享一下Bean自定義初始化和銷毀方法是什么的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
在配置類中指定 @Bean(initMethod = “init”,destroyMethod = “destory”)注解
實現InitializingBean接口并重寫其afterPropertiesSet方法,實現DisposableBean接口并重寫destroy方法
利用java的JSR250規范中的@PostConstruct標注在init方法上,@PreDestroy標注在destroy方法上
1. 方法1:配置類中指定
示例代碼
public class CarA { public CarA() { System.out.println("CarA。。。構造函數"); } public void initCarA(){ System.out.println("CarA的init()方法"); } public void destroyCarA(){ System.out.println("CarA的destroy()方法"); } } @Configuration public class ConfigTest { @Bean(initMethod = "initCarA",destroyMethod = "destroyCarA") public CarA carA(){ return new CarA(); } }
執行結果
CarA。。。構造函數
CarA的init()方法服務啟動
CarA的destroy()方法
2. 方法2:實現接口并重寫方法
2.1 示例代碼
public class CarB implements InitializingBean, DisposableBean { public CarB() { System.out.println("CarB。。。構造函數"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("CarB。。。afterPropertiesSet()方法執行"); } @Override public void destroy() throws Exception { System.out.println("CarB。。。destroy()方法執行"); } } @Configuration public class ConfigTest { @Bean public CarB carB(){ return new CarB(); } }
執行結果
CarB。。。構造函數
CarB。。。afterPropertiesSet()方法執行服務啟動
CarB。。。destroy()方法執行
2.2 概述
Spring 開放了擴展接口,允許我們自定義 bean 的初始化和銷毀方法。即當 Spring 容器在 bean 進行到相應的生命周期階段時,會自動調用我們自定義的初始化和銷毀方法。這兩個擴展接口是 InitializingBean 和 DisposableBean 。
InitializingBean 接口說明:該接口為 bean 提供了 bean 屬性初始化后的處理方法,它只有 afterPropertiesSet 一個方法,凡是實現此接口的類,在 bean 的屬性初始化后都會執行該方法。
package org.springframework.beans.factory;
public interface InitializingBean { void afterPropertiesSet() throws Exception; }
DisposableBean 接口說明:該接口為單例 bean 提供了在容器銷毀 bean 時的處理方法,它只有 destroy 一個方法,凡是實現此接口的類,在 bean 被銷毀時都會執行該方法。
package org.springframework.beans.factory; public interface DisposableBean { void destroy() throws Exception; }
2.3 方法1 && 方法2
相同點:都是在 bean 屬性初始化之后需要執行的初始化方法。
不同點
方法1:代碼不與Spring耦合;執行效率較低(通過反射來執行initMethod 方法)
方法2:代碼與Spring緊耦合;速度更快(將 bean 強制轉換成 InitializingBean 接口類型,然后直接調用 afterPropertiesSet 方法)
說明:afterPropertiesSet 和 initMethod 可以同時存在,但是 afterPropertiesSet 方法是在 initMethod 方法之前執行的。
一個 bean 從創建到初始化的過程總結
通過構造器創建 bean
屬性注入
執行 afterPropertiesSet 方法
執行 initMethod 方法
3. 方法3:利用java的JSR250規范
代碼示例
public class CarC { public CarC() { System.out.println("CarC。。。構造函數"); } @PostConstruct public void initCarC(){ System.out.println("CarC。。。初始化方法initCarC()"); } @PreDestroy public void destroyCarC(){ System.out.println("CarC。。。銷毀方法destroyCarC"); } } @Configuration public class ConfigTest { @Bean public CarC carC(){ return new CarC(); } }
執行結果
CarC。。。構造函數
CarC。。。初始化方法initCarC()服務啟動
CarC。。。銷毀方法destroyCarC
目的是通過注解將特定類的信息(如接口編號)與類關聯,之后可通過接口編號獲取對應bean來執行對應邏輯。
@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Service public @interface ServiceCode { String code() default ""; String className() default ""; }
包含接口編號和beanName信息。
@ServiceCode(code = "100010", className = "echoService") @Service("echoService") public class EchoService { }
來監聽spring容器初始化完成后執行:
@Component @Order(1) public class ServiceInitListener implements ApplicationListener<ContextRefreshedEvent> { private static final Logger LOGGER = LoggerFactory.getLogger(ServiceInitListener.class); @Override public void onApplicationEvent(ContextRefreshedEvent event) { ApplicationContext applicationContext = event.getApplicationContext(); //注意 需要時根容器才能通過注解獲取到bean,比如event直接獲取的容器中只有一些公共注冊bean if (applicationContext.getParent() != null) { applicationContext = applicationContext.getParent(); } Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(ServiceCode.class); for (Object bean : beansWithAnnotation.values()) { ServiceCode annotation = bean.getClass().getAnnotation(ServiceCode.class); String code = annotation.code(); String className = annotation.className(); //注冊接口編號和beanName //在統一入口可通過code獲取beanName,然后通過springContext獲取對應bean執行自定義邏輯 //或者完成其他邏輯 } } }
注意:
ContextRefreshedEvent獲取到的上下文環境不是根spring容器,其中只有部分spring內置bean,無法通過注解獲取到自定義bean,需要獲取其父容器來完成操作。我第一次獲取是beanList總為空,后來發現其容器內部bean沒有自定義的service bean,獲取父容器后操作一切正常。
通過@Order注解來定制執行順序,越小越優先執行。
以上就是“Bean自定義初始化和銷毀方法是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。