亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

深入了解Spring中Bean的作用域和生命周期

 更新時(shí)間:2019年10月30日 11:19:55   作者:流氓大隊(duì)長(zhǎng)  
這篇文章主要介紹了深入了解Spring中Bean的作用域和生命周期,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

作用域的種類

Spring 容器在初始化一個(gè) Bean 的實(shí)例時(shí),同時(shí)會(huì)指定該實(shí)例的作用域。Spring3 為 Bean 定義了五種作用域,具體如下。

1)singleton

單例模式,使用 singleton 定義的 Bean 在 Spring 容器中只有一個(gè)實(shí)例,這也是 Bean 默認(rèn)的作用域。

2)prototype

原型模式,每次通過(guò) Spring 容器獲取 prototype 定義的 Bean 時(shí),容器都將創(chuàng)建一個(gè)新的 Bean 實(shí)例。

3)request

在一次 HTTP 請(qǐng)求中,容器會(huì)返回該 Bean 的同一個(gè)實(shí)例。而對(duì)不同的 HTTP 請(qǐng)求,會(huì)返回不同的實(shí)例,該作用域僅在當(dāng)前 HTTP Request 內(nèi)有效。

4)session

在一次 HTTP Session 中,容器會(huì)返回該 Bean 的同一個(gè)實(shí)例。而對(duì)不同的 HTTP 請(qǐng)求,會(huì)返回不同的實(shí)例,該作用域僅在當(dāng)前 HTTP Session 內(nèi)有效。

5)global Session

在一個(gè)全局的 HTTP Session 中,容器會(huì)返回該 Bean 的同一個(gè)實(shí)例。該作用域僅在使用 portlet context 時(shí)有效。

在上述五種作用域中,singleton 和 prototype 是最常用的兩種,接下來(lái)將對(duì)這兩種作用域進(jìn)行詳細(xì)講解。

singleton 作用域

singleton 是 Spring 容器默認(rèn)的作用域,當(dāng)一個(gè) Bean 的作用域?yàn)?singleton 時(shí),Spring 容器中只會(huì)存在一個(gè)共享的 Bean 實(shí)例,并且所有對(duì) Bean 的請(qǐng)求,只要 id 與該 Bean 定義相匹配,就只會(huì)返回 Bean 的同一個(gè)實(shí)例。

通常情況下,這種單例模式對(duì)于無(wú)會(huì)話狀態(tài)的 Bean(如 DAO 層、Service 層)來(lái)說(shuō),是最理想的選擇。

在 Spring 配置文件中,可以使用 <bean> 元素的 scope 屬性,將 Bean 的作用域定義成 singleton,其配置方式如下所示:

<bean id="person" class="com.mengma.scope.Person" scope="singleton"/>

在項(xiàng)目的 src 目錄下創(chuàng)建一個(gè)名為 com.mengma.scope 的包,在該包下創(chuàng)建 Person 類,類中不需要添加任何成員,然后創(chuàng)建 Spring 的配置文件 applicationContext.xml,將上述 Bean 的定義方式寫(xiě)入配置文件中,最后創(chuàng)建一個(gè)名為 PersonTest 的測(cè)試類,編輯后如下所示。

package com.mengma.scope;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class PersonTest {
@Test
public void test() {
// 定義Spring配置文件路徑
String xmlPath = "com/mengma/scope/applicationContext.xml";
// 初始化Spring容器,加載配置文件,并對(duì)bean進(jìn)行實(shí)例化
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
xmlPath);
// 輸出獲得實(shí)例
System.out.println(applicationContext.getBean("person"));
System.out.println(applicationContext.getBean("person"));
}
}

使用 JUnit 測(cè)試運(yùn)行 test() 方法,運(yùn)行成功后,控制臺(tái)的輸出結(jié)果如圖 1 所示。

圖 1 輸出結(jié)果

從圖 1 中可以看到,兩次輸出的結(jié)果相同,這說(shuō)明 Spring 容器只創(chuàng)建了一個(gè) Person 類的實(shí)例。由于 Spring 容器默認(rèn)作用域是 singleton,如果不設(shè)置 scope="singleton",則其輸出結(jié)果也將是一個(gè)實(shí)例。

prototype 作用域

使用 prototype 作用域的 Bean 會(huì)在每次請(qǐng)求該 Bean 時(shí)都會(huì)創(chuàng)建一個(gè)新的 Bean 實(shí)例。因此對(duì)需要保持會(huì)話狀態(tài)的 Bean(如 Struts2 的 Action 類)應(yīng)該使用 prototype 作用域。

在 Spring 配置文件中,要將 Bean 定義為 prototype 作用域,只需將 <bean> 元素的 scope 屬性值定義成 prototype,其示例代碼如下所示:

<bean id="person" class="com.mengma.scope.Person" scope="prototype"/>

將《singleton作用域》部分中的配置文件更改成上述代碼形式后,再次運(yùn)行 test() 方法,控制臺(tái)的輸出結(jié)果如圖 2 所示。

圖 2 輸出結(jié)果

從圖 2 的輸出結(jié)果中可以看到,兩次輸出的結(jié)果并不相同,這說(shuō)明在 prototype 作用域下,Spring 容器創(chuàng)建了兩個(gè)不同的 Person 實(shí)例。

生命周期

而對(duì)于 prototype 作用域的 Bean,Spring 只負(fù)責(zé)創(chuàng)建,當(dāng)容器創(chuàng)建了 Bean 的實(shí)例后,Bean 的實(shí)例就交給客戶端代碼管理,Spring 容器將不再跟蹤其生命周期。每次客戶端請(qǐng)求 prototype 作用域的 Bean 時(shí),Spring 容器都會(huì)創(chuàng)建一個(gè)新的實(shí)例,并且不會(huì)管那些被配置成 prototype 作用域的 Bean 的生命周期。

了解 Spring 生命周期的意義就在于,可以利用 Bean 在其存活期間的指定時(shí)刻完成一些相關(guān)操作。這種時(shí)刻可能有很多,但一般情況下,會(huì)在 Bean 被初始化后和被銷(xiāo)毀前執(zhí)行一些相關(guān)操作。

在 Spring 中,Bean 的生命周期是一個(gè)很復(fù)雜的執(zhí)行過(guò)程,我們可以利用 Spring 提供的方法定制 Bean 的創(chuàng)建過(guò)程。

當(dāng)一個(gè) Bean 被加載到 Spring 容器時(shí),它就具有了生命,而 Spring 容器在保證一個(gè) Bean 能夠使用之前,會(huì)進(jìn)行很多工作。Spring 容器中 Bean 的生命周期流程如圖3所示。

圖3Bean 的生命周期

Bean 生命周期的整個(gè)執(zhí)行過(guò)程描述如下。

1)根據(jù)配置情況調(diào)用 Bean 構(gòu)造方法或工廠方法實(shí)例化 Bean。

2)利用依賴注入完成 Bean 中所有屬性值的配置注入。

3)如果 Bean 實(shí)現(xiàn)了 BeanNameAware 接口,則 Spring 調(diào)用 Bean 的 setBeanName() 方法傳入當(dāng)前 Bean 的 id 值。

4)如果 Bean 實(shí)現(xiàn)了 BeanFactoryAware 接口,則 Spring 調(diào)用 setBeanFactory() 方法傳入當(dāng)前工廠實(shí)例的引用。

5)如果 Bean 實(shí)現(xiàn)了 ApplicationContextAware 接口,則 Spring 調(diào)用 setApplicationContext() 方法傳入當(dāng)前 ApplicationContext 實(shí)例的引用。

6)如果 BeanPostProcessor 和 Bean 關(guān)聯(lián),則 Spring 將調(diào)用該接口的預(yù)初始化方法 postProcessBeforeInitialzation() 對(duì) Bean 進(jìn)行加工操作,此處非常重要,Spring 的 AOP 就是利用它實(shí)現(xiàn)的。

7)如果 Bean 實(shí)現(xiàn)了 InitializingBean 接口,則 Spring 將調(diào)用 afterPropertiesSet() 方法。

8)如果在配置文件中通過(guò) init-method 屬性指定了初始化方法,則調(diào)用該初始化方法。

9)如果 BeanPostProcessor 和 Bean 關(guān)聯(lián),則 Spring 將調(diào)用該接口的初始化方法 postProcessAfterInitialization()。此時(shí),Bean 已經(jīng)可以被應(yīng)用系統(tǒng)使用了。

10)如果在 <bean> 中指定了該 Bean 的作用范圍為 scope="singleton",則將該 Bean 放入 Spring IoC 的緩存池中,將觸發(fā) Spring 對(duì)該 Bean 的生命周期管理;如果在 <bean> 中指定了該 Bean 的作用范圍為 scope="prototype",則將該 Bean 交給調(diào)用者,調(diào)用者管理該 Bean 的生命周期,Spring 不再管理該 Bean。

11)如果 Bean 實(shí)現(xiàn)了 DisposableBean 接口,則 Spring 會(huì)調(diào)用 destory() 方法將 Spring 中的 Bean 銷(xiāo)毀;如果在配置文件中通過(guò) destory-method 屬性指定了 Bean 的銷(xiāo)毀方法,則 Spring 將調(diào)用該方法對(duì) Bean 進(jìn)行銷(xiāo)毀。

Spring 為 Bean 提供了細(xì)致全面的生命周期過(guò)程,通過(guò)實(shí)現(xiàn)特定的接口或 <bean> 的屬性設(shè)置,都可以對(duì) Bean 的生命周期過(guò)程產(chǎn)生影響。雖然可以隨意配置 <bean> 的屬性,但是建議不要過(guò)多地使用 Bean 實(shí)現(xiàn)接口,因?yàn)檫@樣會(huì)導(dǎo)致代碼和 Spring 的聚合過(guò)于緊密。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot+Redis實(shí)現(xiàn)接口防刷的示例代碼

    SpringBoot+Redis實(shí)現(xiàn)接口防刷的示例代碼

    在實(shí)際開(kāi)發(fā)中,會(huì)出現(xiàn)用戶多次點(diǎn)擊發(fā)送請(qǐng)求,本文主要介紹了SpringBoot+Redis實(shí)現(xiàn)接口防刷的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • java實(shí)現(xiàn)Dijkstra算法

    java實(shí)現(xiàn)Dijkstra算法

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)Dijkstra算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • Idea如何去除Mapper警告方法解析

    Idea如何去除Mapper警告方法解析

    這篇文章主要介紹了Idea如何去除Mapper 警告的方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Java輕松使用工具類實(shí)現(xiàn)獲取MP3音頻時(shí)長(zhǎng)

    Java輕松使用工具類實(shí)現(xiàn)獲取MP3音頻時(shí)長(zhǎng)

    在Java中,工具類定義了一組公共方法,這篇文章將介紹Java中使用工具類來(lái)獲取一個(gè)MP3音頻文件的時(shí)間長(zhǎng)度,感興趣的同學(xué)繼續(xù)往下閱讀吧
    2021-10-10
  • Jackson中json格式的字符串與對(duì)象的互相轉(zhuǎn)換方式

    Jackson中json格式的字符串與對(duì)象的互相轉(zhuǎn)換方式

    這篇文章主要介紹了Jackson中json格式的字符串與對(duì)象的互相轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • SpringBoot啟動(dòng)yaml報(bào)錯(cuò)的解決

    SpringBoot啟動(dòng)yaml報(bào)錯(cuò)的解決

    這篇文章主要介紹了SpringBoot啟動(dòng)yaml報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java中如何獲取相關(guān)參數(shù)

    java中如何獲取相關(guān)參數(shù)

    這篇文章主要介紹了java獲取系統(tǒng)屬性相關(guān)參數(shù)的方法,,需要的朋友可以參考下
    2015-07-07
  • Springboot 如何指定獲取自己寫(xiě)的配置properties文件的值

    Springboot 如何指定獲取自己寫(xiě)的配置properties文件的值

    這篇文章主要介紹了Springboot 如何指定獲取自己寫(xiě)的配置properties文件的值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java中的Io(input與output)操作總結(jié)(二)

    java中的Io(input與output)操作總結(jié)(二)

    這一節(jié)我們來(lái)討論關(guān)于文件自身的操作包括:創(chuàng)建文件對(duì)象、創(chuàng)建和刪除文件、文件的判斷和測(cè)試、創(chuàng)建目錄、獲取文件信息、列出文件系統(tǒng)的根目錄、列出目錄下的所有文件,等等,感興趣的朋友可以了解下
    2013-01-01
  • Java編寫(xiě)時(shí)間工具類ZTDateTimeUtil的示例代碼

    Java編寫(xiě)時(shí)間工具類ZTDateTimeUtil的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用Java編寫(xiě)時(shí)間工具類ZTDateTimeUtil,文中的示例代碼講解詳細(xì),有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11

最新評(píng)論