如何在spring中回調(diào)bean的生命周期

如何在spring中回調(diào)bean的生命周期?針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡(jiǎn)單易行的方法。

作為一家“創(chuàng)意+整合+營(yíng)銷”的成都網(wǎng)站建設(shè)機(jī)構(gòu),我們?cè)跇I(yè)內(nèi)良好的客戶口碑。成都創(chuàng)新互聯(lián)提供從前期的網(wǎng)站品牌分析策劃、網(wǎng)站設(shè)計(jì)、成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)、創(chuàng)意表現(xiàn)、網(wǎng)頁(yè)制作、系統(tǒng)開發(fā)以及后續(xù)網(wǎng)站營(yíng)銷運(yùn)營(yíng)等一系列服務(wù),幫助企業(yè)打造創(chuàng)新的互聯(lián)網(wǎng)品牌經(jīng)營(yíng)模式與有效的網(wǎng)絡(luò)營(yíng)銷方法,創(chuàng)造更大的價(jià)值。

生命周期回調(diào)方法

對(duì)于spring bean來講,我們默認(rèn)可以指定兩個(gè)生命周期回調(diào)方法。一個(gè)是在ApplicationContext將bean初始化,包括注入對(duì)應(yīng)的依賴后的回調(diào)方法;另一個(gè)是在ApplicationContext準(zhǔn)備銷毀之前的回調(diào)方法。要實(shí)現(xiàn)這種回調(diào)主要有三種方式:實(shí)現(xiàn)特定的接口、在XML配置文件中指定回調(diào)方法和使用JSR-250標(biāo)準(zhǔn)的注解。

1 實(shí)現(xiàn)特定接口

針對(duì)bean初始化后的回調(diào)和ApplicationContext銷毀前的回調(diào),Spring分別為我們了提供了InitializingBean和DisposableBean接口供用戶實(shí)現(xiàn),這樣Spring在需要進(jìn)行回調(diào)時(shí)就會(huì)調(diào)用對(duì)應(yīng)接口提供的回調(diào)方法。

1.1 InitializingBean

InitializingBean是用來定義ApplicationContext在完全初始化一個(gè)bean以后需要需要回調(diào)的方法的,其中只定義了一個(gè)afterPropertiesSet()方法。如其名稱所描述的那樣,該方法將在ApplicationContext將一個(gè)bean完全初始化,包括將對(duì)應(yīng)的依賴項(xiàng)都注入以后才會(huì)被調(diào)用。InitializingBean的完全定義如下。

public interface InitializingBean {

 void afterPropertiesSet() throws Exception;

}

由于InitializingBean的afterPropertiesSet()方法會(huì)在依賴項(xiàng)都進(jìn)行注入以后再回調(diào),所以該方法通常會(huì)用來檢查必要的依賴注入,以使我們能夠在bean被初始化時(shí)就發(fā)現(xiàn)其中的錯(cuò)誤,而不是在很長(zhǎng)時(shí)間使用以后才發(fā)現(xiàn)。如果你去看Spring的源碼,你就會(huì)發(fā)現(xiàn)源碼中有很多InitializingBean的使用,而且基本都是用來檢查必要的依賴項(xiàng)是否為空的。

public class Hello implements InitializingBean {
 
 private World world;
 
 /**
 * 該方法將在當(dāng)前bean被完全初始化后被調(diào)用
 */
 public void afterPropertiesSet() throws Exception {
 Assert.notNull(world, "world should not be null.");
 }

 public void setWorld(World world) {
 this.world = world;
 }
 
}

9.1.2 DisposableBean

DisposableBean是用來定義在ApplicationContext銷毀之前需要回調(diào)的方法的。DisposableBean接口中只定義了一個(gè)destroy()方法,在ApplicationContext被銷毀前,Spring將依次調(diào)用bean容器中實(shí)現(xiàn)了DisposableBean接口的destroy()方法。所以,我們可以通過實(shí)現(xiàn)該接口的destroy()方法來達(dá)到在ApplicationContext銷毀前釋放某些特定資源的目的。

public interface DisposableBean {

 void destroy() throws Exception;

}

在Spring的源碼中,也有很多實(shí)現(xiàn)了DisposableBean接口的類,如我們熟悉的ApplicationContext實(shí)現(xiàn)類、SingleConnectionDataSource等。

2 在XML中配置回調(diào)方法

在XML配置文件中通過bean元素定義一個(gè)bean時(shí),我們可以通過bean元素的init-method屬性和destroy-method屬性來指定當(dāng)前bean在初始化以后和ApplicationContext銷毀前的回調(diào)方法。需要注意的是所指定的回調(diào)方法必須是沒有參數(shù)的。

通過init-method屬性來指定初始化方法時(shí)所對(duì)應(yīng)的方法必須是該bean中所擁有的方法,所以首先我們需要在對(duì)應(yīng)的bean中定義對(duì)應(yīng)的初始化方法,這里假設(shè)我們需要在bean中定義一個(gè)init()方法作為該bean的初始化方法,那么我們可以對(duì)我們的bean進(jìn)行類似如下定義。

public class Hello {
 
 private World world;
 
 /**
 * 該方法將被用來作為初始化方法,在當(dāng)前bean被完全初始化后被調(diào)用
 */
 public void init() {
 Assert.notNull(world, "world should not be null.");
 }

 public void setWorld(World world) {
 this.world = world;
 }
 
}

接下來就是在XML配置文件中定義該bean時(shí)通過init-method屬性定義對(duì)應(yīng)的初始化方法為init()方法,init-method屬性的屬性值就對(duì)應(yīng)初始化方法的名稱,所以我們的bean應(yīng)該是如下定義。

 <bean name="world" class="com.app.World"/>
 <!-- 通過init-method屬性指定初始化方法名稱 -->
 <bean id="hello" class="com.app.Hello" init-method="init">
 <property name="world" ref="world"/>
 </bean>

init-method和destroy-method的用法和配置等基本上都是一樣的,所以對(duì)于使用destroy-method來指定ApplicationContext銷毀前的回調(diào)方法的用法就不再贅述了。

如果我們的初始化方法或銷毀方法的名稱大都是一樣的,在通過init-method和destroy-method進(jìn)行指定的時(shí)候我們就沒有必要一個(gè)個(gè)bean都去指定了,Spring允許我們?cè)谧铐敿?jí)的beans元素上指定默認(rèn)的初始化后回調(diào)方法和銷毀前的回調(diào)方法名稱,這樣對(duì)于沒有指定init-method或destroy-method的bean將默認(rèn)將其中default-init-method或default-destroy-method屬性值對(duì)應(yīng)名稱的方法(如果存在的話)視為初始化后的回調(diào)方法或銷毀前的回調(diào)方法。這是通過default-init-method和default-destroy-method屬性來定義的。

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd"
  default-init-method="init" default-destroy-method="destroy">
 
</beans>

以上表示定義默認(rèn)的初始化后回調(diào)方法名稱為init,默認(rèn)的銷毀前回調(diào)方法名稱為destroy。

當(dāng)定義了default-init-method或default-destroy-method以后,如果我們的某個(gè)bean對(duì)應(yīng)的初始化后回調(diào)方法名稱或銷毀前的回調(diào)方法名稱與默認(rèn)定義的不一樣,則我們可以在對(duì)應(yīng)的bean上通過init-method或destroy-method指定該bean自身的回調(diào)方法名稱,即bean上定義的回調(diào)方法名稱將會(huì)比默認(rèn)定義擁有更高的優(yōu)先級(jí)。

3 使用JSR-250標(biāo)準(zhǔn)的注解

關(guān)于bean的生命周期回調(diào)方法,Spring也會(huì)JSR-250標(biāo)準(zhǔn)注解做了支持,即在bean完全初始化后將回調(diào)使用@PostConstruct標(biāo)注的方法,在銷毀ApplicationContext前將回調(diào)使用@PreDestroy標(biāo)注的方法。
針對(duì)之前的示例,如果我們現(xiàn)在把定義的bean定義成如下這樣,即沒有在bean上通過init-method和destroy-method指定初始化方法和銷毀方法。

 <bean name="world" class="com.app.World"/>
 <bean id="hello" class="com.app.Hello">
 <property name="world" ref="world"/>
 </bean>

當(dāng)然,這里也不考慮全局性的init-method和destroy-method方法,如果我們希望在id為“hello”的bean被初始化后回調(diào)其中的init()方法,在銷毀前回調(diào)其中的destroy()方法,我們就可以通過@PostConstruct和@PreDestroy進(jìn)行如下定義。

public class Hello {
 
 private World world;
 
 /**
 * 該方法將被用來作為初始化方法,在當(dāng)前bean被完全初始化后被調(diào)用
 */
 @PostConstruct
 public void init() {
 Assert.notNull(world, "world should not be null.");
 }
 
 @PreDestroy
 public void destroy() {
 System.out.println("---------destroy-----------");
 }

 public void setWorld(World world) {
 this.world = world;
 }
 
}

使用JSR-250標(biāo)準(zhǔn)指定初始化后的回調(diào)方法以及銷毀前的回調(diào)方法時(shí),如果我們希望將多個(gè)方法都作為對(duì)應(yīng)的回調(diào)方法進(jìn)行回調(diào),則可以在多個(gè)方法上同時(shí)使用對(duì)應(yīng)的注解進(jìn)行標(biāo)注,Spring將依次執(zhí)行對(duì)應(yīng)的方法。

public class Hello {
 
 private World world;

 @PostConstruct
 public void init() {
 System.out.println("-----------init-------------");
 }
 
 /**
 * 該方法將被用來作為初始化方法,在當(dāng)前bean被完全初始化后被調(diào)用
 */
 @PostConstruct
 public void init2() {
 Assert.notNull(world, "world should not be null.");
 }
 
 @PreDestroy
 public void destroy() {
 System.out.println("------------destroy----------------");
 }
 
 @PreDestroy
 public void destroy2() {
 System.out.println("---------destroy2-----------");
 }

 public void setWorld(World world) {
 this.world = world;
 }
 
}

4 混合使用三種方式

Spring允許我們混合使用上述介紹的三種方式來指定對(duì)應(yīng)的回調(diào)方法。當(dāng)對(duì)于同一個(gè)bean使用三種方式指定了同一個(gè)方法作為初始化后的回調(diào)方法或銷毀前的回調(diào)方法,則對(duì)應(yīng)的回調(diào)方法只會(huì)被執(zhí)行一次。然而,當(dāng)對(duì)于同一個(gè)bean使用兩種或三種方式指定的回調(diào)方法不是同一個(gè)方法時(shí),Spring將依次執(zhí)行使用不同的方式指定的回調(diào)方法。對(duì)于初始化后的回調(diào)方法而言,具體規(guī)則如下:

  1. 使用@PostConstruct標(biāo)注的方法。

  2. 實(shí)現(xiàn)InitializingBean接口后的回調(diào)方法afterPropertiesSet()方法。

  3. 通過init-method或default-init-method指定的方法。

對(duì)于銷毀前的回調(diào)方法而言,其規(guī)則是一樣的:

  1. 使用@PreDestroy標(biāo)注的方法。

  2. 實(shí)現(xiàn)DisposableBean接口后的回調(diào)方法destroy()方法。

  3. 通過destroy-method或default-destroy-method指定的方法。

關(guān)于如何在spring中回調(diào)bean的生命周期問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

網(wǎng)頁(yè)題目:如何在spring中回調(diào)bean的生命周期
網(wǎng)頁(yè)鏈接:http://muchs.cn/article8/ishdop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、手機(jī)網(wǎng)站建設(shè)、定制開發(fā)、服務(wù)器托管用戶體驗(yàn)、商城網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)