[Java]03.Spring Bean作用域

Bean 的范圍:

范圍 描述
singleton (默認(rèn))將單個(gè) bean 定義范圍限定為每個(gè) Spring IoC 容器的單個(gè)對(duì)象實(shí)例周崭。
prototype 將單個(gè) bean 定義范圍限定為任意數(shù)量的對(duì)象實(shí)例冤狡。
request 將單個(gè) bean 定義范圍限定為單個(gè) HTTP 請(qǐng)求的生命周期。也就是說(shuō)垮兑,每個(gè) HTTP 請(qǐng)求都有自己的 bean 實(shí)例族檬,該 bean 實(shí)例是在單個(gè) bean 定義的后面創(chuàng)建的硬鞍。僅在 web-aware Spring 的上下文中有效ApplicationContext
session 將單個(gè) bean 定義范圍限定為 HTTP 的生命周期Session酷勺。僅在 web-aware Spring 的上下文中有效ApplicationContext本橙。
application 將單個(gè) bean 定義范圍限定為ServletContext. 僅在 web-aware Spring 的上下文中有效ApplicationContext
websocket 將單個(gè) bean 定義范圍限定為WebSocket. 僅在 web-aware Spring 的上下文中有效ApplicationContext脆诉。

單例作用域

當(dāng)您定義一個(gè) bean 定義并且它的作用域是一個(gè)單例時(shí)甚亭,Spring IoC 容器會(huì)創(chuàng)建該 bean 定義定義的對(duì)象的一個(gè)實(shí)例。該單個(gè)實(shí)例存儲(chǔ)在此類單例 bean 的緩存中库说,并且對(duì)該命名 bean 的所有后續(xù)請(qǐng)求和引用都返回緩存對(duì)象狂鞋。下圖顯示了單例范圍的工作原理:

單身人士

Spring 的單例 bean 概念不同于四人組 (GoF) 模式書中定義的單例模式。GoF 單例對(duì)對(duì)象的范圍進(jìn)行了硬編碼潜的,以便每個(gè) ClassLoader 只創(chuàng)建一個(gè)特定類的一個(gè)實(shí)例骚揍。Spring 單例的范圍最好描述為每個(gè)容器和每個(gè) bean。這意味著,如果您在單個(gè) Spring 容器中為特定類定義一個(gè) bean信不,則 Spring 容器會(huì)創(chuàng)建該 bean 定義定義的類的一個(gè)且僅一個(gè)實(shí)例嘲叔。單例作用域是 Spring 中的默認(rèn)作用域。要將 bean 定義為 XML 中的單例抽活,您可以定義一個(gè) bean硫戈,如下例所示:

<bean id="accountService" class="com.something.DefaultAccountService"/>

<!-- the following is equivalent, though redundant (singleton scope is the default) -->
<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>

原型范圍

bean 部署的非單一原型范圍導(dǎo)致每次對(duì)特定 bean 發(fā)出請(qǐng)求時(shí)都會(huì)創(chuàng)建一個(gè)新 bean 實(shí)例。也就是說(shuō)下硕,bean 被注入到另一個(gè) bean 中丁逝,或者您通過(guò)getBean()容器上的方法調(diào)用來(lái)請(qǐng)求它。通常梭姓,您應(yīng)該對(duì)所有有狀態(tài) bean 使用原型作用域霜幼,對(duì)無(wú)狀態(tài) bean 使用單例作用域。

下圖說(shuō)明了 Spring 原型范圍:

原型

(數(shù)據(jù)訪問(wèn)對(duì)象 (DAO) 通常不配置為原型誉尖,因?yàn)榈湫偷?DAO 不保存任何對(duì)話狀態(tài)罪既。我們更容易重用單例圖的核心。)

以下示例將 bean 定義為 XML 中的原型:

<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>

與其他作用域相比铡恕,Spring 不管理原型 bean 的完整生命周期琢感。容器實(shí)例化、配置和以其他方式組裝原型對(duì)象并將其交給客戶端探熔,沒(méi)有該原型實(shí)例的進(jìn)一步記錄驹针。因此,盡管在所有對(duì)象上調(diào)用初始化生命周期回調(diào)方法祭刚,而不管范圍如何牌捷,但在原型的情況下墙牌,不會(huì)調(diào)用配置的銷毀生命周期回調(diào)涡驮。客戶端代碼必須清理原型范圍內(nèi)的對(duì)象并釋放原型 bean 持有的昂貴資源喜滨。要讓 Spring 容器釋放原型作用域 bean 持有的資源捉捅,請(qǐng)嘗試使用自定義bean post-processor,它保存對(duì)需要清理的 bean 的引用虽风。

在某些方面棒口,Spring 容器在原型作用域 bean 方面的角色是 Javanew運(yùn)算符的替代品。超過(guò)該點(diǎn)的所有生命周期管理都必須由客戶端處理辜膝。

請(qǐng)求无牵、會(huì)話、應(yīng)用程序和 WebSocket 范圍

request厂抖,session茎毁,application,和websocket范圍只有當(dāng)你使用一個(gè)基于web的Spring在ApplicationContext實(shí)現(xiàn)(例如 XmlWebApplicationContext)。如果將這些作用域與常規(guī) Spring IoC 容器(例如 )一起使用ClassPathXmlApplicationContext七蜘,IllegalStateException則會(huì)拋出抱怨未知 bean 作用域的 谭溉。

請(qǐng)求范圍

考慮以下 bean 定義的 XML 配置:

<bean id="loginAction" class="com.something.LoginAction" scope="request"/>

Spring 容器LoginAction通過(guò)loginAction對(duì)每個(gè) HTTP 請(qǐng)求使用bean 定義來(lái)創(chuàng)建bean 的新實(shí)例。也就是說(shuō)橡卤, loginActionbean 的范圍在 HTTP 請(qǐng)求級(jí)別扮念。您可以根據(jù)需要更改所創(chuàng)建實(shí)例的內(nèi)部狀態(tài),因?yàn)閺耐?code>loginActionbean 定義創(chuàng)建的其他實(shí)例看不到這些狀態(tài)更改碧库。它們是針對(duì)個(gè)人要求的柜与。當(dāng)請(qǐng)求完成處理時(shí),該請(qǐng)求范圍內(nèi)的 bean 將被丟棄嵌灰。

當(dāng)使用注解驅(qū)動(dòng)的組件或 Java 配置時(shí)旅挤,@RequestScope注解可用于將組件分配給request作用域。以下示例顯示了如何執(zhí)行此操作:

@RequestScope
@Component
public class LoginAction {
    // ...
}
會(huì)話范圍

考慮以下 bean 定義的 XML 配置:

<bean id="userPreferences" class="com.something.UserPreferences" scope="session"/>

Spring 容器UserPreferences通過(guò)在userPreferences單個(gè) HTTP 的生命周期中使用bean 定義來(lái)創(chuàng)建bean 的新實(shí)例Session伞鲫。換句話說(shuō)粘茄,userPreferencesbean 有效地限定在 HTTPSession級(jí)別。與請(qǐng)求范圍的 bean 一樣秕脓,您可以根據(jù)需要更改所創(chuàng)建實(shí)例的內(nèi)部狀態(tài)柒瓣,因?yàn)橹榔渌?code>Session也在使用從相同userPreferencesbean 定義創(chuàng)建的實(shí)例的HTTP實(shí)例不會(huì)看到這些狀態(tài)更改,因?yàn)樗鼈兲囟ㄓ趩蝹€(gè) HTTP Session吠架。當(dāng) HTTPSession最終被丟棄時(shí)芙贫,作用域?yàn)樵撎囟?HTTP 的 bean Session也將被丟棄。

當(dāng)使用注解驅(qū)動(dòng)的組件或 Java 配置時(shí)傍药,您可以使用 @SessionScope注解將組件分配給session作用域磺平。

@SessionScope
@Component
public class UserPreferences {
    // ...
}
應(yīng)用程序范圍

考慮以下 bean 定義的 XML 配置:

<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>

Spring 容器AppPreferences通過(guò)appPreferences對(duì)整個(gè) Web 應(yīng)用程序使用一次 bean 定義來(lái)創(chuàng)建bean 的新實(shí)例。也就是說(shuō)拐辽, appPreferencesbean 的作用域在ServletContext級(jí)別并存儲(chǔ)為常規(guī) ServletContext屬性拣挪。這有點(diǎn)類似于 Spring 單例 bean,但在兩個(gè)重要方面有所不同:它是一個(gè)單例 per ServletContext俱诸,而不是 per Spring ApplicationContext(在任何給定的 Web 應(yīng)用程序中可能有多個(gè))菠劝,并且它實(shí)際上是公開的,因此作為一個(gè)ServletContext屬性可見.

當(dāng)使用注解驅(qū)動(dòng)的組件或 Java 配置時(shí)睁搭,您可以使用 @ApplicationScope注解將組件分配給application作用域赶诊。以下示例顯示了如何執(zhí)行此操作:

@ApplicationScope
@Component
public class AppPreferences {
    // ...
}

以上文檔來(lái)自Spring官方網(wǎng)站,關(guān)于 Spring-framework 文檔 Bean作用域介紹园骆。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末舔痪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子锌唾,更是在濱河造成了極大的恐慌锄码,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異巍耗,居然都是意外死亡秋麸,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門炬太,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)灸蟆,“玉大人,你說(shuō)我怎么就攤上這事亲族〕纯迹” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵霎迫,是天一觀的道長(zhǎng)斋枢。 經(jīng)常有香客問(wèn)我,道長(zhǎng)知给,這世上最難降的妖魔是什么瓤帚? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮涩赢,結(jié)果婚禮上戈次,老公的妹妹穿的比我還像新娘。我一直安慰自己筒扒,他們只是感情好怯邪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著花墩,像睡著了一般悬秉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上冰蘑,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天和泌,我揣著相機(jī)與錄音,去河邊找鬼懂缕。 笑死允跑,一個(gè)胖子當(dāng)著我的面吹牛王凑,可吹牛的內(nèi)容都是我干的搪柑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼索烹,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼工碾!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起百姓,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤渊额,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體旬迹,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡火惊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了奔垦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屹耐。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖椿猎,靈堂內(nèi)的尸體忽然破棺而出惶岭,到底是詐尸還是另有隱情,我是刑警寧澤犯眠,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布按灶,位于F島的核電站,受9級(jí)特大地震影響筐咧,放射性物質(zhì)發(fā)生泄漏鸯旁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一量蕊、第九天 我趴在偏房一處隱蔽的房頂上張望羡亩。 院中可真熱鬧,春花似錦危融、人聲如沸畏铆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)辞居。三九已至,卻和暖如春蛋勺,著一層夾襖步出監(jiān)牢的瞬間瓦灶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工抱完, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留贼陶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓巧娱,卻偏偏與公主長(zhǎng)得像碉怔,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子禁添,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容