Spring(四):Bean的作用域

摘自:http://jinnianshilongnian.iteye.com/blog/1415463

Bean的作用域

什么是作用域呢?即“scope”,在面向?qū)ο蟪绦蛟O(shè)計中一般指對象或變量之間的可見范圍先改。而在Spring容器中是指其創(chuàng)建的Bean對象相對于其他Bean對象的請求可見范圍蒸走。

Spring提供“singleton”和“prototype”兩種基本作用域,另外提供“request”该溯、“session”别惦、“global session”三種web作用域;Spring還允許用戶定制自己的作用域氯庆。

基本的作用域

singleton:

指“singleton”作用域的Bean只會在每個Spring IoC容器中存在一個實例扰付,而且其完整生命周期完全由Spring容器管理。對于所有獲取該Bean的操作Spring容器將只返回同一個Bean实昨。

GoF單例設(shè)計模式指“保證一個類僅有一個實例荒给,并提供一個訪問它的全局訪問點”,介紹了兩種實現(xiàn):通過在類上定義靜態(tài)屬性保持該實例和通過注冊表方式志电。

1)通過在類上定義靜態(tài)屬性保持該實例:

一般指一個Java虛擬機 ClassLoader裝載的類只有一個實例蛔趴,一般通過類靜態(tài)屬性保持該實例,這樣就造成需要單例的類都需要按照單例設(shè)計模式進(jìn)行編碼之拨;Spring沒采用這種方式咧叭,因為該方式屬于侵入式設(shè)計菲茬。

public class Singleton {  
    //1.私有化構(gòu)造器  
    private Singleton() {}  
    //2.單例緩存者,惰性初始化睬魂,第一次使用時初始化  
    private static class InstanceHolder {  
        private static final Singleton INSTANCE = new Singleton();  
    }  
    //3.提供全局訪問點  
    public static Singleton getInstance() {  
        return InstanceHolder.INSTANCE;  
    }  
    //4.提供一個計數(shù)器來驗證一個ClassLoader一個實例  
    private int counter=0;  
} 

2)通過注冊表方式:

首先將需要單例的實例通過唯一鍵注冊到注冊表氯哮,然后通過鍵來獲取單例商佛,讓我們直接看實現(xiàn)吧,注意本注冊表實現(xiàn)了Spring接口“SingletonBeanRegistry”肠虽,該接口定義了操作共享的單例對象玛追,Spring容器實現(xiàn)將實現(xiàn)此接口;所以共享單例對象通過“registerSingleton”方法注冊韩玩,通過“getSingleton”方法獲取陆馁,消除了編程方式單例。

public class SingletonBeanRegister implements SingletonBeanRegistry {  
    //單例Bean緩存池叮雳,此處不考慮并發(fā)  
    private final Map<String, Object> BEANS = new HashMap<String, Object>();  
    public boolean containsSingleton(String beanName){  
        return BEANS.containsKey(beanName);  
    }  
    public Object getSingleton(String beanName) {  
        return BEANS.get(beanName);  
    }  
    @Override  
    public int getSingletonCount() {  
        return BEANS.size();  
    }  
    @Override  
    public String[] getSingletonNames() {  
        return BEANS.keySet().toArray(new String[0]);  
    }  
    @Override  
    public void registerSingleton(String beanName, Object bean) {  
        if(BEANS.containsKey(beanName)) {  
            throw new RuntimeException("[" + beanName + "] 已存在");  
        }  
        BEANS.put(beanName, bean);  
    }  
}  

Spring是注冊表單例設(shè)計模式的實現(xiàn)帘不,消除了編程式單例寞焙,而且對代碼是非入侵式互婿。

接下來讓我們看看在Spring中如何配置單例Bean吧,在Spring容器中如果沒指定作用域默認(rèn)就是“singleton”呛牲,配置方式通過scope屬性配置驮配,具體配置如下:

<bean  class="cn.javass.spring.chapter3.bean.Printer" scope="singleton"/>  

Spring不僅會緩存單例對象着茸,Bean定義也是會緩存的涮阔,對于惰性初始化的對象是在首次使用時根據(jù)Bean定義創(chuàng)建并存放于單例緩存池灰殴。

3-5.JPG

prototype:

即原型,指每次向Spring容器請求獲取Bean都返回一個全新的Bean伟阔,相對于“singleton”來說就是不緩存Bean义图,每次都是一個根據(jù)Bean定義創(chuàng)建的全新Bean。

GoF原型設(shè)計模式娃承,指用原型實例指定創(chuàng)建對象的種類怕篷,并且通過拷貝這些原型創(chuàng)建新的對象。

Spring中的原型和GoF中介紹的原型含義是不一樣的:

  • GoF通過用原型實例指定創(chuàng)建對象的種類梳猪,而Spring容器用Bean定義指定創(chuàng)建對象的種類蒸痹;
  • GoF通過拷貝這些原型創(chuàng)建新的對象,而Spring容器根據(jù)Bean定義創(chuàng)建新對象匿沛。

其相同地方都是根據(jù)某些東西創(chuàng)建新東西逃呼,而且GoF原型必須顯示實現(xiàn)克隆操作,屬于侵入式抡笼,而Spring容器只需配置即可黄鳍,屬于非侵入式。

只需指定<bean>標(biāo)簽屬性“scope”屬性為“prototype”即可:

<bean class="cn.javass.spring.chapter3.bean.Printer" scope="prototype"/>

Spring管理原型對象在Spring容器中存儲如圖3-6所示拾碌,Spring不會緩存原型對象街望,而是根據(jù)Bean定義每次請求返回一個全新的Bean:

3-6.JPG

Web應(yīng)用中的作用域

在Web應(yīng)用中,我們可能需要將數(shù)據(jù)存儲到request防症、session哎甲、global session。因此Spring提供了三種Web作用域:request奈嘿、session吞加、globalSession。

一衔憨、request作用域:

表示每個請求需要容器創(chuàng)建一個全新Bean。比如提交表單的數(shù)據(jù)必須是對每次請求新建一個Bean來保持這些表單數(shù)據(jù)掺冠,請求結(jié)束釋放這些數(shù)據(jù)码党。

二、session作用域:

表示每個會話需要容器創(chuàng)建一個全新Bean眉厨。比如對于每個用戶一般會有一個會話缺猛,該用戶的用戶信息需要存儲到會話中椭符,此時可以將該Bean配置為web作用域。

三销钝、globalSession:

類似于session作用域蒸健,只是其用于portlet環(huán)境的web應(yīng)用婉商。如果在非portlet環(huán)境將視為session作用域丈秩。

配置方式和基本的作用域相同淳衙,只是必須要有web環(huán)境支持,并配置相應(yīng)的容器監(jiān)聽器或攔截器從而能應(yīng)用這些作用域肠牲,我們會在集成web時講解具體使用靴跛,大家只需要知道有這些作用域就可以了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肥印,一起剝皮案震驚了整個濱河市扬绪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌莹痢,老刑警劉巖墓赴,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诫硕,死亡現(xiàn)場離奇詭異,居然都是意外死亡章办,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進(jìn)店門挪蹭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來梁厉,“玉大人踏兜,你說我怎么就攤上這事八秃∥羟” “怎么了垮媒?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵航棱,是天一觀的道長。 經(jīng)常有香客問我它抱,道長朴艰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任侮穿,我火速辦了婚禮亲茅,結(jié)果婚禮上狗准,老公的妹妹穿的比我還像新娘。我一直安慰自己袭祟,他們只是感情好捞附,可當(dāng)我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著胆绊,像睡著了一般药版。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上何缓,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天,我揣著相機與錄音传轰,去河邊找鬼。 笑死慨蛙,一個胖子當(dāng)著我的面吹牛纪挎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播通砍,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼烤蜕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了虎忌?” 一聲冷哼從身側(cè)響起橱鹏,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蚀瘸,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贪惹,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡奏瞬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年泉孩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片珍昨。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖兔毙,靈堂內(nèi)的尸體忽然破棺而出兄春,到底是詐尸還是另有隱情,我是刑警寧澤赶舆,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站叙量,受9級特大地震影響夕晓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蒸辆,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一躬贡、第九天 我趴在偏房一處隱蔽的房頂上張望眼坏。 院中可真熱鬧,春花似錦檐蚜、人聲如沸沿侈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至咙好,卻和暖如春褐荷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工绘迁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留缀台,地道東北人。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓膛腐,卻偏偏與公主長得像哲身,于是被迫代替她去往敵國和親贸伐。 傳聞我的和親對象是個殘疾皇子勘天,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,724評論 2 351

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