一文詳解spring注解配置bean的初始化方法和銷毀方法
本篇我們講解下spring項目中如何為bean指定初始化方法和銷毀方法。當(dāng)spring完成bean的屬性賦值之后,就會執(zhí)行bean的初始化方法,而當(dāng)spring要銷毀bean實例的時候,也會調(diào)用bean的銷毀方法。我們可以在初始化方法中做一些資源加載的操作,比如緩存數(shù)據(jù)到redis。而在銷毀方法中,可以做一些資源釋放的操作,比如刪除redis緩存數(shù)據(jù)、釋放數(shù)據(jù)庫連接等。由于我們現(xiàn)在很少寫spring的xml文件,所以這次就講解通過注解的方式來指定bean的初始化方法和銷毀方法。我們先定義如下的配置類、業(yè)務(wù)服務(wù)類和單元測試方法,供后面測試使用。
package?com.xk.spring.init;
import?org.springframework.context.annotation.Bean;
import?org.springframework.context.annotation.Configuration;
/**?測試初始化方法和銷毀方法
?*
?*?@author?xk
?*?@since?2023.04.30?15:31
?*/
@Configuration
public?class?InitConfig?{
????@Bean
????public?RedisService?redisService(){
????????return?new?RedisService();
????}
}package?com.xk.spring.init;
/**
?*?用于如何配置講解bean的初始化方法
?*?@author?xk
?*?@since?2023.04.30?15:26
?*/
public?class?RedisService{
????public?RedisService(){
????????System.out.println("這是RedisService構(gòu)造方法");
????}
}單元測試方法如下:
????@Test
????public?void?testInitAndDestroyConfig(){
????????AnnotationConfigApplicationContext?applicationContext?=?new?AnnotationConfigApplicationContext(InitConfig.class);
????????applicationContext.close();
????}1、配置bean的初始化方法
1.1、使用@Bean注解的initMethod屬性
我們在配置類中使用@Bean注解生成bean實例的時候,可以使用@Bean注解的initMethod屬性指定初始化方法,initMethod的值是目標(biāo)bean對應(yīng)的類中的方法名,當(dāng)spring完成bean的屬性賦值之后,就會執(zhí)行initMethod對應(yīng)的這個方法。
修改RedisService服務(wù)類內(nèi)容如下,增加自定義的initMethod方法:
package?com.xk.spring.init;
/**
?*?用于如何配置講解bean的初始化方法
?*?@author?xk
?*?@since?2023.04.30?15:26
?*/
public?class?RedisService?{
????public?RedisService(){
????????System.out.println("這是RedisService構(gòu)造方法");
????}
????public?void?initMethod(){
????????System.out.println("(1)這是一個@Bean?initMethod初始化方法");
????}
}修改InitConfig配置類如下,指定@Bean注解的initMethod屬性值為RedisService類中的initMethod方法:
package?com.xk.spring.init;
import?org.springframework.context.annotation.Bean;
import?org.springframework.context.annotation.Configuration;
/**?測試初始化方法和銷毀方法
?*
?*?@author?xk
?*?@since?2023.04.30?15:31
?*/
@Configuration
public?class?InitConfig?{
????@Bean(initMethod?=?"initMethod")
????public?RedisService?redisService(){
????????return?new?RedisService();
????}
}最后執(zhí)行testInitAndDestroyConfig單元測試方法,得出如下結(jié)果:
這是RedisService構(gòu)造方法 (1)這是一個@Bean?initMethod初始化方法
1.2、使用@PostConstruct注解
@PostConstruct注解用于在bean完成依賴注入(屬性賦值)之后需要執(zhí)行的方法上,它是被用在bean對應(yīng)的類中定義的方法,而且一個類中只能有一個方法被標(biāo)記@PostConstruct注解。只要方法所屬的類不是攔截器類而且方法本身無參且沒有返回值,那就可以在這個方法上面使用@PostConstruct注解。(如果方法所屬類的是攔截器類,在滿足一定的要求時也可以使用@PostConstruct注解,但這種情況很少使用,所以此處先不提。)我們保持InitConfig類不變,修改RedisService類內(nèi)容如下:
package?com.xk.spring.init;
import?javax.annotation.PostConstruct;
/**
?*?用于如何配置講解bean的初始化方法
?*?@author?xk
?*?@since?2023.04.30?15:26
?*/
public?class?RedisService{
????public?RedisService(){
????????System.out.println("這是RedisService構(gòu)造方法");
????}
????public?void?initMethod(){
????????System.out.println("(1)這是一個@Bean?initMethod初始化方法");
????}
????
????@PostConstruct
????private?void?initMethod2(){
????????System.out.println("(2)這是一個@PostConstruct初始化方法");
????}
}最后執(zhí)行testInitAndDestroyConfig單元測試方法,得出如下結(jié)果:
這是RedisService構(gòu)造方法 (2)這是一個@PostConstruct初始化方法 (1)這是一個@Bean?initMethod初始化方法
可以看出,標(biāo)記@PostConstruct注解的方法要比@Bean注解的InitMethod屬性指定的方法先執(zhí)行。
1.3、實現(xiàn)InitializingBean接口
InitializingBean接口只有一個afterPropertiesSet方法,假如一個bean完成了屬性賦值,并且這個bean對應(yīng)的類實現(xiàn)了該接口,spring就會調(diào)用afterPropertiesSet方法。我們繼續(xù)在前兩步的基礎(chǔ)上進(jìn)行修改,保持InitConfig類不變,修改RedisService類如下:
package?com.xk.spring.init;
import?org.springframework.beans.factory.InitializingBean;
import?javax.annotation.PostConstruct;
/**
?*?用于如何配置講解bean的初始化方法
?*?@author?xk
?*?@since?2023.04.30?15:26
?*/
public?class?RedisService?implements?InitializingBean?{
????public?RedisService(){
????????System.out.println("這是RedisService構(gòu)造方法");
????}
????public?void?initMethod(){
????????System.out.println("(1)這是一個@Bean?initMethod初始化方法");
????}
????@PostConstruct
????private?void?initMethod2(){
????????System.out.println("(2)這是一個@PostConstruct初始化方法");
????}
????@Override
????public?void?afterPropertiesSet()?throws?Exception?{
????????System.out.println("(3)這是一個InitializingBean初始化方法");
????}
}最后執(zhí)行單元測試,得出結(jié)果如下:
這是RedisService構(gòu)造方法 (2)這是一個@PostConstruct初始化方法 (3)這是一個InitializingBean初始化方法 (1)這是一個@Bean?initMethod初始化方法
1.4、總結(jié)
bean的初始化方法調(diào)用位于bean的屬性賦值之后,我們可以同時使用以上三種方式來指定bean的初始化方法,而且執(zhí)行順序如下:
@PostConstruct指定的方法-->InitializingBean接口的afterPropertiesSet方法-->@Bean的initMethod屬性指定的方法
2、配置bean的銷毀方法
2.1、使用@Bean注解的destroyMethod屬性
我們在配置類中使用@Bean注解生成bean實例的時候,可以使用@Bean注解的destroyMethod屬性指定bean的銷毀方法,destroyMethod的值是目標(biāo)bean對應(yīng)的類中的方法名,當(dāng)spring完成bean的屬性賦值之后,就會執(zhí)行destroyMethod對應(yīng)的這個方法。
我們修改RedisService服務(wù)類內(nèi)容如下,增加自定義的destroyMethod方法:
package?com.xk.spring.init;
import?org.springframework.beans.factory.InitializingBean;
import?javax.annotation.PostConstruct;
/**
?*?用于如何配置講解bean的初始化方法
?*?@author?xk
?*?@since?2023.04.30?15:26
?*/
public?class?RedisService?implements?InitializingBean?{
????public?RedisService(){
????????System.out.println("這是RedisService構(gòu)造方法");
????}
????public?void?initMethod(){
????????System.out.println("(1)這是一個@Bean?initMethod初始化方法");
????}
????@PostConstruct
????private?void?initMethod2(){
????????System.out.println("(2)這是一個@PostConstruct初始化方法");
????}
????@Override
????public?void?afterPropertiesSet()?throws?Exception?{
????????System.out.println("(3)這是一個InitializingBean初始化方法");
????}
????public?void?destroyMethod(){
????????System.out.println("(1)這是一個@Bean?destroyMethod銷毀方法");
????}
}修改InitConfig配置類如下,指定@Bean注解的destroyMethod屬性值為RedisService類中的destroyMethod方法:
package?com.xk.spring.init;
import?org.springframework.context.annotation.Bean;
import?org.springframework.context.annotation.Configuration;
/**?測試初始化方法和銷毀方法
?*
?*?@author?xk
?*?@since?2023.04.30?15:31
?*/
@Configuration
public?class?InitConfig?{
????@Bean(initMethod?=?"initMethod",destroyMethod?=?"destroyMethod")
????public?RedisService?redisService(){
????????return?new?RedisService();
????}
}最后執(zhí)行testInitAndDestroyConfig單元測試方法,得出如下結(jié)果:
這是RedisService構(gòu)造方法 (2)這是一個@PostConstruct初始化方法 (3)這是一個InitializingBean初始化方法 (1)這是一個@Bean?initMethod初始化方法 (1)這是一個@Bean?destroyMethod銷毀方法
2.2、使用@PreDestroy注解
@PreDestroy注解用于在bean被銷毀時需要執(zhí)行的方法上,它是被用在bean對應(yīng)的類中定義的方法,而且一個類中只能有一個方法被標(biāo)記@PreDestroy注解。只要方法所屬的類不是攔截器類而且方法本身無參且沒有返回值,那就可以在這個方法上面使用@PreDestroy注解。(如果方法所屬類的是攔截器類,在滿足一定的要求時也可以使用@PreDestroyt注解,但這種情況很少使用,所以此處先不提。)我們保持InitConfig類不變,修改RedisService類內(nèi)容如下:
package?com.xk.spring.init;
import?org.springframework.beans.factory.DisposableBean;
import?org.springframework.beans.factory.InitializingBean;
import?javax.annotation.PostConstruct;
import?javax.annotation.PreDestroy;
/**
?*?用于如何配置講解bean的初始化方法
?*?@author?xk
?*?@since?2023.04.30?15:26
?*/
public?class?RedisService?implements?InitializingBean,?DisposableBean?{
????public?RedisService(){
????????System.out.println("這是RedisService構(gòu)造方法");
????}
????public?void?initMethod(){
????????System.out.println("(1)這是一個@Bean?initMethod初始化方法");
????}
????@PostConstruct
????private?void?initMethod2(){
????????System.out.println("(2)這是一個@PostConstruct初始化方法");
????}
????@Override
????public?void?afterPropertiesSet()?throws?Exception?{
????????System.out.println("(3)這是一個InitializingBean初始化方法");
????}
????public?void?destroyMethod(){
????????System.out.println("(1)這是一個@Bean?destroyMethod銷毀方法");
????}
????@PreDestroy
????public?void?destroyMethod2()?{
????????System.out.println("(2)這是一個@PreDestroy銷毀方法");
????}
}最后執(zhí)行testInitAndDestroyConfig單元測試方法,得出如下結(jié)果:
這是RedisService構(gòu)造方法 (2)這是一個@PostConstruct初始化方法 (3)這是一個InitializingBean初始化方法 (1)這是一個@Bean?initMethod初始化方法 (2)這是一個@PreDestroy銷毀方法 (1)這是一個@Bean?destroyMethod銷毀方法
可以看出,標(biāo)記@PreDestroy注解的方法要比@Bean注解的destroyMethod屬性指定的方法先執(zhí)行。
2.3、實現(xiàn)DisposableBean接口
DisposableBean接口只有一個destroy方法,假如一個bean對應(yīng)的類實現(xiàn)了該接口,spring在bean(或容器)銷毀時就會調(diào)用destroy方法。我們繼續(xù)在前面代碼的基礎(chǔ)上進(jìn)行修改,保持InitConfig類不變,修改RedisService類如下:
package?com.xk.spring.init;
import?org.springframework.beans.factory.DisposableBean;
import?org.springframework.beans.factory.InitializingBean;
import?javax.annotation.PostConstruct;
import?javax.annotation.PreDestroy;
/**
?*?用于如何配置講解bean的初始化方法
?*?@author?xk
?*?@since?2023.04.30?15:26
?*/
public?class?RedisService?implements?InitializingBean,?DisposableBean?{
????public?RedisService(){
????????System.out.println("這是RedisService構(gòu)造方法");
????}
????public?void?initMethod(){
????????System.out.println("(1)這是一個@Bean?initMethod初始化方法");
????}
????@PostConstruct
????private?void?initMethod2(){
????????System.out.println("(2)這是一個@PostConstruct初始化方法");
????}
????@Override
????public?void?afterPropertiesSet()?throws?Exception?{
????????System.out.println("(3)這是一個InitializingBean初始化方法");
????}
????public?void?destroyMethod(){
????????System.out.println("(1)這是一個@Bean?destroyMethod銷毀方法");
????}
????@PreDestroy
????public?void?destroyMethod2()?{
????????System.out.println("(2)這是一個@PreDestroy銷毀方法");
????}
????@Override
????public?void?destroy()?throws?Exception?{
????????System.out.println("(3)這是一個DisposableBean銷毀方法");
????}
}最后執(zhí)行單元測試,得出結(jié)果如下:
這是RedisService構(gòu)造方法 (2)這是一個@PostConstruct初始化方法 (3)這是一個InitializingBean初始化方法 (1)這是一個@Bean?initMethod初始化方法 (2)這是一個@PreDestroy銷毀方法 (3)這是一個DisposableBean銷毀方法 (1)這是一個@Bean?destroyMethod銷毀方法
2.4、總結(jié)
bean的銷毀方法調(diào)用位于bean(或容器)被銷毀的時候,我們可以同時使用以上三種方式來指定bean的銷毀方法,而且執(zhí)行順序如下:
@PreDestroy指定的方法-->DisposableBean接口的destroy方法-->@Bean的destroyMethod屬性指定的方法
以上就是一文詳解spring注解配置bean的初始化方法和銷毀方法的詳細(xì)內(nèi)容,更多關(guān)于spring注解配置bean初始化方法和銷毀方法的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java避免UTF-8的csv文件打開中文出現(xiàn)亂碼的方法
這篇文章主要介紹了Java避免UTF-8的csv文件打開中文出現(xiàn)亂碼的方法,結(jié)合實例形式分析了java操作csv文件時使用utf-16le編碼與utf8編碼相關(guān)操作技巧,需要的朋友可以參考下2019-07-07
利用SpringMVC接收復(fù)雜對象和多個文件(前端使用JQuery)
這篇文章主要介紹了利用SpringMVC接收復(fù)雜對象和多個文件(前端使用JQuery),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
Java8?stream流分組groupingBy的使用方法代碼
對于java8的新特性groupingBy方法,相信有很多人都在工作中用過,這篇文章主要給大家介紹了關(guān)于Java8?stream流分組groupingBy的使用方法,需要的朋友可以參考下2024-01-01

