Spring中Bean初始化和銷毀的方式總結(jié)
Spring中支持在Bean的加載時(shí)聲明初始化方法,該方法會(huì)在Bean對(duì)象完成初始化之前進(jìn)行執(zhí)行,可以為對(duì)象指定一些特定的行為,同樣的Bean銷毀時(shí),也是支持這個(gè)動(dòng)作的。其中因?yàn)閷?duì)象的作用域不同,銷毀的表現(xiàn)形式略有區(qū)別。初始化都沒(méi)有區(qū)別,無(wú)論是單例、原型、request、session、global session等他們的創(chuàng)建時(shí)初始化都沒(méi)啥區(qū)別,但是銷毀會(huì)略有區(qū)別,單例模式默認(rèn)不會(huì)銷毀,只有在Spring容器被銷毀時(shí)才會(huì)執(zhí)行Bean的銷毀,從而執(zhí)行他的銷毀方法。session、request等他們是作用范圍到了就會(huì)被銷毀,并不會(huì)長(zhǎng)期存在,所以他們的銷毀方法是在作用范圍執(zhí)行之后來(lái)調(diào)用的。
一、Bean的多種初始化方式
Spring中總共支持了三種方式對(duì)Bean進(jìn)行初始化,依次是在方法上使用PostConstruct注解、實(shí)現(xiàn)InitializtingBean接口重寫(xiě)對(duì)應(yīng)方法、聲明init-method方法來(lái)實(shí)現(xiàn),且他們?nèi)齻€(gè)支持并行。也就是說(shuō)我們可以三個(gè)都是用,當(dāng)三個(gè)都是用時(shí)就是按照下面的順序執(zhí)行的,即限制性PostConstruct注解的方法,再執(zhí)行InitializingBean的方法,最終執(zhí)行init-method的方法。
1.PostConstruct注解
如下所示,這里使用配置類的方式進(jìn)行注入,因?yàn)橐粫?huì)延時(shí)init-method必須使用配置類才可以實(shí)現(xiàn),啟動(dòng)容器當(dāng)加載TestA這個(gè)Bean時(shí),他的初始化方法就會(huì)被執(zhí)行。
@Configuration
public class TestInitmestond {
@Bean
public TestA getBeanA(){
return new TestA();
}
}
class TestA{
@PostConstruct
public void postConstructor(){
System.out.println("這是使用了PostConstruct注解的初始化方法");
}
}
2.實(shí)現(xiàn)InitializingBean接口
下面是結(jié)合了第一種和第二種的初始化方式:
@Configuration
public class TestInitmestond {
@Bean
public TestA getBeanA(){
return new TestA();
}
}
class TestA implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("這是實(shí)現(xiàn)InitializingBean的初始化方法");
}
@PostConstruct
public void postConstructor(){
System.out.println("這是使用了PostConstruct注解的初始化方法");
}
}
3.聲明init-method方法
init-method方法必須使用配置類進(jìn)行加載Bean才可以配置,因?yàn)樵搶傩允荁ean標(biāo)簽的屬性,在注解中也就是Bean注解的屬性,所以我們使用Component等其他IOC注解時(shí)是無(wú)法指定的。
@Configuration
public class TestInitmestond {
@Bean(initMethod = "initMethod")
public TestA getBeanA(){
return new TestA();
}
}
class TestA implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("這是實(shí)現(xiàn)InitializingBean的初始化方法");
}
@PostConstruct
public void postConstructor(){
System.out.println("這是使用了PostConstruct注解的初始化方法");
}
public void initMethod(){
System.out.println("這是使用了init-method聲明的初始化方法");
}
}
下面啟動(dòng)下容器展示下他們的執(zhí)行順序,如下:

可以看到他們的順序是固定的即:PostConstruct—>initializingBean—>init-method.
二、Bean的多種銷毀方式
同樣的Spring也支持了三種銷毀的方式,且這三種銷毀方式與三種創(chuàng)建方式是完全對(duì)應(yīng)的。同時(shí)與初始化方法一樣Spring也是支持三種銷毀方法的并行的。且他們并行時(shí)順序是固定的:執(zhí)行PreDestroy–>DisposableBean–>destroy-method.
1.PreDestroy注解
這里容器采用手動(dòng)啟動(dòng)的方式進(jìn)行創(chuàng)建,然后為容器設(shè)置一個(gè)銷毀的鉤子,這樣當(dāng)容器銷毀時(shí)我們就可以去執(zhí)行銷毀方法了,對(duì)于單例模式的銷毀方法只能通過(guò)這種測(cè)試了,若是我們直接停止IDEA的服務(wù)是不會(huì)執(zhí)行銷毀方法的。不過(guò)對(duì)于scope不是singleton的Bean來(lái)說(shuō),比如request在正常服務(wù)里是可以體現(xiàn)銷毀動(dòng)作的。
public class TestDestroyMethod {
//手動(dòng)啟動(dòng)容器,模擬關(guān)閉
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(TestConfig.class);
annotationConfigApplicationContext.start();
annotationConfigApplicationContext.registerShutdownHook();
}
}
@Configuration
class TestConfig{
@Bean
public TestB getBean(){
return new TestB();
}
}
class TestB{
@PreDestroy
public void preDestroy(){
System.out.println("這是使用PreDestroy注解的銷毀方法");
}
}
2.實(shí)現(xiàn)DisposableBean接口
這種就是直接實(shí)現(xiàn)接口重寫(xiě)destroy方法即可
public class TestDestroyMethod {
//手動(dòng)啟動(dòng)容器,模擬關(guān)閉
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(TestConfig.class);
annotationConfigApplicationContext.start();
annotationConfigApplicationContext.registerShutdownHook();
}
}
@Configuration
class TestConfig{
@Bean
public TestB getBean(){
return new TestB();
}
}
class TestB implements DisposableBean {
@PreDestroy
public void preDestroy(){
System.out.println("這是使用PreDestroy注解的銷毀方法");
}
@Override
public void destroy() throws Exception {
System.out.println("這是實(shí)現(xiàn)DisposableBean的方法");
}
}
3.聲明destroy-method方法
下面是結(jié)合了三種銷毀方法的代碼
public class TestDestroyMethod {
//手動(dòng)啟動(dòng)容器,模擬關(guān)閉
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(TestConfig.class);
annotationConfigApplicationContext.start();
annotationConfigApplicationContext.registerShutdownHook();
}
}
@Configuration
class TestConfig{
@Bean(destroyMethod = "destroyMethod")
public TestB getBean(){
return new TestB();
}
}
class TestB implements DisposableBean {
@PreDestroy
public void preDestroy(){
System.out.println("這是使用PreDestroy注解的銷毀方法");
}
@Override
public void destroy() throws Exception {
System.out.println("這是實(shí)現(xiàn)DisposableBean的方法");
}
public void destroyMethod(){
System.out.println("這是制定了destroy-method的銷毀方法");
}
}
下面是執(zhí)行的截圖,可以看到三種銷毀方式與初始化方式一樣都是有固定順序的,事實(shí)上初始化方式與銷毀方式他們是有對(duì)應(yīng)關(guān)系的。PostConstruct與PreDestroy是一組,InitializingBean與DisposableBean是一組,init-method與destroy-method是一組。

到此這篇關(guān)于Spring中Bean初始化和銷毀的方式總結(jié)的文章就介紹到這了,更多相關(guān)Spring Bean內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解SpringBoot啟動(dòng)類的掃描注解的用法及沖突原則
這篇文章主要介紹了詳解SpringBoot啟動(dòng)類的掃描注解的用法及沖突原則,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
15道非常經(jīng)典的Java面試題 附詳細(xì)答案
這篇文章主要為大家推薦了15道非常經(jīng)典的Java面試題,附詳細(xì)答案,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10
淺談Java中Lock和Synchronized的區(qū)別
這篇文章主要介紹了Java中Lock和Synchronized的區(qū)別,Lock和Synchronized都是java中去用來(lái)解決線程安全問(wèn)題的一個(gè)工具,但是具體有什么區(qū)別呢?下面我們一起進(jìn)入文章了解具體詳細(xì)內(nèi)容吧,需要的朋友可以參考一下2022-04-04
Springboot2.6.x的啟動(dòng)流程與自動(dòng)配置詳解
這篇文章主要給大家介紹了關(guān)于Springboot2.6.x的啟動(dòng)流程與自動(dòng)配置的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-01-01
SpringBoot 如何使用RestTemplate發(fā)送Post請(qǐng)求
這篇文章主要介紹了SpringBoot 如何使用RestTemplate發(fā)送Post請(qǐng)求的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
JDBC下Idea添加mysql-jar包的詳細(xì)過(guò)程
這篇文章主要介紹了JDBC下Idea添加mysql-jar包的詳細(xì)過(guò)程,添加jar包首先到官網(wǎng)下載jar包,然后idea導(dǎo)入jar包,在就是檢查,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-11-11
解決Mybatis查詢方法selectById()主鍵不一致問(wèn)題
這篇文章主要介紹了解決Mybatis查詢方法selectById()主鍵不一致問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
java使用DOM對(duì)XML文檔進(jìn)行增刪改查操作實(shí)例代碼
這篇文章主要介紹了java使用DOM對(duì)XML文檔進(jìn)行增刪改查操作實(shí)例代碼,實(shí)例涉及對(duì)xml文檔的增刪改查,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-02-02
Java?Apache?common-pool對(duì)象池介紹
這篇文章主要介紹了Java Apache?common-pool對(duì)象池介紹,文章通過(guò)圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下2022-09-09
java通過(guò)信號(hào)量實(shí)現(xiàn)限流的示例
本文主要介紹了java通過(guò)信號(hào)量實(shí)現(xiàn)限流的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06

