摘自《Spring 解密》java
scope用來聲明IOC容器中的對象應該處的限定場景或者說該對象的存活空間,即在IOC容器在 對象進入相應的scope以前,生成並裝配這些對象,在該對象再也不處於這些scope的限定以後,容器一般會銷燬這些對象。打個比方吧!咱們都是處在社會 (容器)中,若是把中學教師做爲一個類定義,那麼當容器初始化這些類以後,中學教師只能侷限在中學這個場景中,中學,就能夠看作中學教師的scope。web
Spring容器最初提供了兩種bean的scope類型:singleton和 prototype,但發佈2.0以後,又引入了另外三種scope類型,即request,session和global session類型。不過這三種類型有所限制,只能在web應用中使用,也就是說,只有在支持web應用的ApplicationContext中使用這 三個scope纔是合理的。spring
可使用bean的singleton或scope屬性來指定相應對象的scope,其中,scope屬性只能在XSD格式的文檔生命中使用,相似於以下代碼所演示的形式:設計模式
DTD:session
<bean id ="mockObject1" class="..." singleton="false" />spa
XSD:prototype
<bean id ="mockObject1" class="..." scope="prototype" />設計
注意:這裏的singleton和設計模式裏面的單例模式不同,標記爲singleton的bean是由容器來保證這種類型的bean在同一個容器內只存在一個共享實例,而單例模式則是保證在同一個Classloader中只存在一個這種類型的實例。對象
1. singleton生命週期
singleton類型的bean定義,在一個容器中只存在一個實例,全部對該類型bean的依賴都引用這一單一實例,這就好像每一個幼兒園都會有一個滑梯同樣,這個幼兒園的小朋友共同使用這一個滑梯,而對於幼兒園容器來講,滑梯就是一個singleton的bean。
此外,singleton類型的bean定義,從容器啓動,到他第一次被請求而實例化開始,只要容器不銷燬或退出,該類型的bean的單一實例就會一直存活。
一般狀況下,若是你不指定bean的scope,singleton即是容器默認的scope,因此,下面三種配置,形式實際上達成的是一樣的效果:
DTD or XSD:
<bean id ="mockObject1" class="..." />
DTD:
<bean id ="mockObject1" class="..." singleton="true" />
XSD:
<bean id ="mockObject1" class="..." scope="singleton" />
2 prototype
scope爲prototype的bean,容器在接受到該類型的對象的請求的時候,會每次都從新 生成一個新的對象給請求方,雖然這種類型的對象的實例化以及屬性設置等工做都是由容器負責的,可是隻要準備完畢,而且對象實例返回給請求方以後,容器就不 在擁有當前對象的引用,請求方須要本身負責當前對象後繼生命週期的管理工做,包括該對象的銷燬。也就是說,容器每次返回請求方該對象的一個新的實例以後, 就由這個對象「自生自滅」了。
讓咱們繼續幼兒園的比喻,咱們今天要分蘋果了!將蘋果的bean的scope屬性聲明爲 prototype,在每一個小朋友領取蘋果的時候,咱們都是發一個新的蘋果給他,發完以後,小朋友愛怎麼吃就怎麼吃,愛何時吃何時吃,可是注意吃 完要把果核扔到垃圾箱哦!對於那些不能共享使用的對象類型,應該將其定義的scope設爲prototype,一般,聲明爲prototype的的 bean,都是一些有狀態的,好比保存爲每一個顧客信息的對象。
能夠用一下方式定義prototype類型的bean:
DTD:
<bean id ="mockObject1" class="..." singleton="false" />
XSD:
<bean id ="mockObject1" class="..." scope="prototype" />
3 request ,session和global session
這三個類型是spring2.0以後新增的,他們不像singleton和prototype那麼通用,由於他們只適用於web程序,一般是和XmlWebApplicationContext共同使用,將在第6章詳細討論,這裏簡單介紹。
request:
<bean id ="requestPrecessor" class="...RequestPrecessor" scope="request" />
Spring容器,即XmlWebApplicationContext 會爲每一個HTTP請求建立一個全新的RequestPrecessor對象,當請求結束後,,該對象的生命週期即告結束。當同時有10個HTTP請求進來 的時候,容器會分別針對這10個請求建立10個全新的RequestPrecessor實例,且他們相互之間互不干擾,從不是很嚴格的意義上 說,request能夠看作prototype的一種特例,除了場景更加具體以外,語意上差很少。
session:
對於web應用來講,放到session中最廣泛的就是用戶的登陸信息,對於這種放到session中的信息,咱們咱們可使用以下形式的制定scope爲session:
<bean id ="userPreferences" class="...UserPreferences" scope="session" />
Spring容器會爲每一個獨立的session建立屬於本身的全新的UserPreferences實例,他比request scope的bean會存活更長的時間,其餘的方面真是沒什麼區別。
global session:
<bean id ="userPreferences" class="...UserPreferences" scope="globalsession" />
global session只有應用在基於porlet的web應用程序中才有意義,他映射到porlet的global範圍的session,若是普通的servlet的web 應用中使用了這個scope,容器會把它做爲普通的session的scope對待。
(我只是據說過porlet這個詞,好像是和servlet相似的一種java web技術,你們之後遇到的時候能夠搜一下!)
spring還支持一種自定義scope類型,我就很少寫了,有點累了。。。之後還會寫更多的筆記,你們敬請期待~