SpringBoot中Bean生命周期自定義初始化和銷毀方法詳解
一、@Bean注解指定初始化和銷毀方法
創(chuàng)建BeanTest類,自定義初始化方法和銷毀方法。在@Bean注解的參數(shù)中指定BeanTest自定義的初始化和銷毀方法:銷毀方法只有在IOC容器關(guān)閉的時(shí)候才調(diào)用。
代碼如下:
/** * @Version: 1.0.0 * @Author: Dragon_王 * @ClassName: dog * @Description: TODO描述 * @Date: 2024/1/21 22:55 */ public class BeanTest { public BeanTest(){ System.out.println("BeanTest被創(chuàng)建"); } public void init(){ System.out.println("BeanTest被初始化"); } public void destory(){ System.out.println("BeanTest被銷毀"); } } /** * @Version: 1.0.0 * @Author: Dragon_王 * @ClassName: MyConfig * @Description: TODO描述 * @Date: 2024/1/21 22:59 */ @Configuration @ComponentScan(("com.dragon.restart1")) public class MyConfig { @Bean(initMethod = "init",destroyMethod = "destory") public BeanTest beanTest(){ return new BeanTest(); } } //測(cè)試代碼 AnnotationConfigApplicationContext ct = new AnnotationConfigApplicationContext(MyConfig.class); System.out.println("IoC容器創(chuàng)建完成");
- 可以看到調(diào)用的是自定義的方法,這里解釋一下,測(cè)試時(shí),運(yùn)行完代碼塊程序就結(jié)束了,所喲IoC容器就被關(guān)閉,所以調(diào)用了IoC銷毀方法。同時(shí)可以看到初始化方法在對(duì)象創(chuàng)建完成后調(diào)用。
- 當(dāng)組件的作用域?yàn)閱卫龝r(shí)在容器啟動(dòng)時(shí)即創(chuàng)建對(duì)象,而當(dāng)作用域?yàn)樵停≒ROTOTYPE)時(shí)在每次獲取對(duì)象的時(shí)候才創(chuàng)建對(duì)象。并且當(dāng)作用域?yàn)樵?/strong>(PROTOTYPE)時(shí),IOC容器只負(fù)責(zé)創(chuàng)建Bean但不會(huì)管理Bean,所以IOC容器不會(huì)調(diào)用銷毀方法。
二、實(shí)現(xiàn)InitializingBean接口和DisposableBean接口
看一下兩接口的方法:
public interface InitializingBean { /** * Invoked by the containing {@code BeanFactory} after it has set all bean properties * and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc. * <p>This method allows the bean instance to perform validation of its overall * configuration and final initialization when all bean properties have been set. * @throws Exception in the event of misconfiguration (such as failure to set an * essential property) or if initialization fails for any other reason * Bean都裝配完成后執(zhí)行初始化 */ void afterPropertiesSet() throws Exception; } ==================================================================== public interface DisposableBean { /** * Invoked by the containing {@code BeanFactory} on destruction of a bean. * @throws Exception in case of shutdown errors. Exceptions will get logged * but not rethrown to allow other beans to release their resources as well. */ void destroy() throws Exception; }
代碼如下:
/** * @Version: 1.0.0 * @Author: Dragon_王 * @ClassName: BeanTest1 * @Description: TODO描述 * @Date: 2024/1/21 23:25 */ public class BeanTest1 implements InitializingBean, DisposableBean { @Override public void destroy() throws Exception { System.out.println("BeanTest1銷毀"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("BeanTest1初始化"); } public BeanTest1() { System.out.println("BeanTest1被創(chuàng)建"); } } ========================= @Configuration @ComponentScan(("com.dragon.restart1")) public class MyConfig { @Bean public BeanTest1 beanTest1(){ return new BeanTest1(); } }
三、@PostConstruct(初始化邏輯)和@PreDestroy(銷毀邏輯)注解
- 被@PostConstruct修飾的方法會(huì)在服務(wù)器加載Servlet的時(shí)候運(yùn)行,并且只會(huì)被服務(wù)器調(diào)用一次,類似于Serclet的inti()方法。
- 被@PostConstruct修飾的方法會(huì)在構(gòu)造函數(shù)之后,init()方法之前運(yùn)行。
- 被@PreDestroy修飾的方法會(huì)在服務(wù)器卸載Servlet的時(shí)候運(yùn)行,并且只會(huì)被服務(wù)器調(diào)用一次,類似于Servlet的destroy()方法。被@PreDestroy修飾的方法會(huì)在destroy()方法之后運(yùn)行,在Servlet被徹底卸載之前。
代碼如下:
/** * @Version: 1.0.0 * @Author: Dragon_王 * @ClassName: BeanTest2 * @Description: TODO描述 * @Date: 2024/1/21 23:32 */ public class BeanTest2 { public BeanTest2(){ System.out.println("BeanTest2被創(chuàng)建"); } @PostConstruct public void init(){ System.out.println("BeanTest2被初始化"); } @PreDestroy public void destory(){ System.out.println("BeanTest2被銷毀"); } } ======================== // @Configuration @ComponentScan(("com.dragon.restart1")) public class MyConfig { @Bean public BeanTest2 beanTest2(){ return new BeanTest2(); } }
四、BeanPostProcessor接口
BeanPostProcessor又叫Bean的后置處理器,是Spring框架中IOC容器提供的一個(gè)擴(kuò)展接口,在Bean初始化的前后進(jìn)行一些處理工作。
BeanPostProcessor的源碼如下:
public interface BeanPostProcessor { /** * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean * initialization callbacks (like InitializingBean's {@code afterPropertiesSet} * or a custom init-method). The bean will already be populated with property values. * The returned bean instance may be a wrapper around the original. * <p>The default implementation returns the given {@code bean} as-is. * @param bean the new bean instance * @param beanName the name of the bean * @return the bean instance to use, either the original or a wrapped one; * if {@code null}, no subsequent BeanPostProcessors will be invoked * @throws org.springframework.beans.BeansException in case of errors * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet */ @Nullable //bean初始化方法調(diào)用前被調(diào)用 default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } /** * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean * initialization callbacks (like InitializingBean's {@code afterPropertiesSet} * or a custom init-method). The bean will already be populated with property values. * The returned bean instance may be a wrapper around the original. * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean * instance and the objects created by the FactoryBean (as of Spring 2.0). The * post-processor can decide whether to apply to either the FactoryBean or created * objects or both through corresponding {@code bean instanceof FactoryBean} checks. * <p>This callback will also be invoked after a short-circuiting triggered by a * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method, * in contrast to all other BeanPostProcessor callbacks. * <p>The default implementation returns the given {@code bean} as-is. * @param bean the new bean instance * @param beanName the name of the bean * @return the bean instance to use, either the original or a wrapped one; * if {@code null}, no subsequent BeanPostProcessors will be invoked * @throws org.springframework.beans.BeansException in case of errors * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet * @see org.springframework.beans.factory.FactoryBean */ @Nullable //bean初始化方法調(diào)用后被調(diào)用 default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; }
代碼如下:
/** * @Version: 1.0.0 * @Author: Dragon_王 * @ClassName: MyBeanPostProcess * @Description: TODO描述 * @Date: 2024/1/21 23:40 */ @Component public class MyBeanPostProcess implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean); return bean; } } ============================ @Configuration @ComponentScan(("com.dragon.restart1")) public class MyConfig { @Bean public BeanTest1 beanTest1(){ return new BeanTest1(); } @Bean public BeanTest2 beanTest2(){ return new BeanTest2(); } }
運(yùn)行結(jié)果如下:
BeanTest1被創(chuàng)建 postProcessBeforeInitialization...beanTest1=>com.dragon.restart1.BeanTest1@111d5c97 BeanTest1初始化 postProcessAfterInitialization...beanTest1=>com.dragon.restart1.BeanTest1@111d5c97 BeanTest2被創(chuàng)建 postProcessBeforeInitialization...beanTest2=>com.dragon.restart1.BeanTest2@29c17c3d BeanTest2被初始化 postProcessAfterInitialization...beanTest2=>com.dragon.restart1.BeanTest2@29c17c3d IoC容器創(chuàng)建完成 BeanTest2被銷毀 BeanTest1銷毀
通過(guò)上述運(yùn)行結(jié)果可以發(fā)現(xiàn)使用BeanPostProcessor的運(yùn)行順序?yàn)?/strong>:
IOC容器實(shí)例化Bean---->調(diào)用BeanPostProcessor的postProcessBeforeInitialization方法---->調(diào)用bean實(shí)例的初始化方法---->調(diào)用BeanPostProcessor的postProcessAfterInitialization方法。
總結(jié)
以上就是Bean生命周期自定義初始化和銷毀的講解。
到此這篇關(guān)于SpringBoot中Bean生命周期自定義初始化和銷毀方法詳解的文章就介紹到這了,更多相關(guān)SpringBoot Bean初始化和銷毀內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用Java搭建個(gè)簡(jiǎn)單的Netty通信實(shí)例教程
這篇文章主要給大家介紹了關(guān)于如何利用Java搭建個(gè)簡(jiǎn)單的Netty通信,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05關(guān)于Mybatis-Plus?Update更新策略問(wèn)題
這篇文章主要介紹了關(guān)于Mybatis-Plus?Update更新策略問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11ByteArrayInputStream簡(jiǎn)介和使用_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
ByteArrayInputStream 是字節(jié)數(shù)組輸入流。它繼承于InputStream。這篇文章主要介紹了ByteArrayInputStream簡(jiǎn)介和使用_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理,需要的朋友可以參考下2017-05-05springcloud如何用Redlock實(shí)現(xiàn)分布式鎖
本文主要介紹了springcloud如何用Redlock實(shí)現(xiàn)分布式鎖,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11SpringCloud?分布式鎖的多種實(shí)現(xiàn)
本文主要介紹了SpringCloud?分布式鎖的多種實(shí)現(xiàn),主要有三種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04