国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

Spring Bean的作用域

2019-11-14 20:51:00
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
SPRing Bean的作用域Spring Bean的作用域
作用域描述

singleton

在每個(gè)Spring IoC容器中一個(gè)bean定義對(duì)應(yīng)一個(gè)對(duì)象實(shí)例。

prototype

一個(gè)bean定義對(duì)應(yīng)多個(gè)對(duì)象實(shí)例。

request

在一次HTTP請(qǐng)求中,一個(gè)bean定義對(duì)應(yīng)一個(gè)實(shí)例;即每次HTTP請(qǐng)求將會(huì)有各自的bean實(shí)例,它們依據(jù)某個(gè)bean定義創(chuàng)建而成。該作用域僅在基于web的SpringapplicationContext情形下有效。

session

在一個(gè)HTTPSession中,一個(gè)bean定義對(duì)應(yīng)一個(gè)實(shí)例。該作用域僅在基于web的SpringApplicationContext情形下有效。

global session

在一個(gè)全局的HTTPSession中,一個(gè)bean定義對(duì)應(yīng)一個(gè)實(shí)例。典型情況下,僅在使用portlet context的時(shí)候有效。該作用域僅在基于web的SpringApplicationContext情形下有效。

  Singleton作用域

當(dāng)一個(gè)bean的作用域?yàn)閟ingleton, 那么Spring IoC容器中只會(huì)存在一個(gè)共享的bean實(shí)例,并且所有對(duì)bean的請(qǐng)求,只要id與該bean定義相匹配,則只會(huì)返回bean的同一實(shí)例。

換言之,當(dāng)把一個(gè)bean定義設(shè)置為singlton作用域時(shí),Spring IoC容器只會(huì)創(chuàng)建該bean定義的唯一實(shí)例。這個(gè)單一實(shí)例會(huì)被存儲(chǔ)到單例緩存(singleton cache)中,并且所有針

對(duì)該bean的后續(xù)請(qǐng)求和引用都將返回被緩存的對(duì)象實(shí)例。

  Prototype作用域

Prototype作用域的bean會(huì)導(dǎo)致在每次對(duì)該bean請(qǐng)求(將其注入到另一個(gè)bean中,或者以程序的方式調(diào)用容器的getBean()方法)時(shí)都會(huì)創(chuàng)建一個(gè)新的bean實(shí)例。根據(jù)經(jīng)驗(yàn),對(duì)所

有有狀態(tài)的bean應(yīng)該使用prototype作用域,而對(duì)無(wú)狀態(tài)的bean則應(yīng)該使用singleton作用域。

  其他作用域

    requestsession以及global session僅在基于web的應(yīng)用中使用(不必關(guān)心你所采用的是什么web應(yīng)用框架)。

    注意

下面介紹的作用域僅僅在使用基于web的SpringApplicationContext實(shí)現(xiàn)(如xmlWebApplicationContext)時(shí)有用。如果在普通的Spring IoC容器中,比如像XmlBeanFactory

ClassPathXmlApplicationContext,嘗試使用這些作用域,你將會(huì)得到一個(gè)IllegalStateException異常(未知的bean作用域)。

   初始化web配置

    要使用requestsessionglobal session作用域的bean(即具有web作用域的bean),在開(kāi)始設(shè)置bean定義之前,還要做少量的初始配置。請(qǐng)注意,假如你只想要“常規(guī)的”作用域,也就是singleton和prototype,就不需要這一額外的設(shè)置。

在目前的情況下,根據(jù)你的特定servlet環(huán)境,有多種方法來(lái)完成這一初始設(shè)置。如果你使用的是Servlet 2.4及以上的web容器,那么你僅需要在web應(yīng)用的XML聲明文件web.xml中增加下述ContextListener即可

 <listener>       <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>   </listener>

如果你用的是早期版本的web容器(Servlet 2.4以前),那么你要使用一個(gè)javax.servlet.Filter的實(shí)現(xiàn)。請(qǐng)看下面的web.xml配置片段:

<filter>          <filter-name>requestContextFilter</filter-name>                    <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>   </filter>    <filter-mapping>          <filter-name>requestContextFilter</filter-name>          <url-pattern>/*</url-pattern>   </filter-mapping>

RequestContextListenerRequestContextFilter兩個(gè)類(lèi)做的都是同樣的工作:將HTTP request對(duì)象綁定到為該請(qǐng)求提供服務(wù)的Thread。這使得具有request和session作用域的bean能夠在后面的調(diào)用鏈中被訪(fǎng)問(wèn)到。

  Request作用域<bean id="loginAction" class="com.foo.LoginAction" scope="request"/>

針對(duì)每次HTTP請(qǐng)求,Spring容器會(huì)根據(jù)loginActionbean定義創(chuàng)建一個(gè)全新的LoginActionbean實(shí)例,且該loginActionbean實(shí)例僅在當(dāng)前HTTP request內(nèi)有效,因此可以根據(jù)需要放心的更改所建實(shí)例的內(nèi)部狀態(tài),而其他請(qǐng)求中根據(jù)loginActionbean定義創(chuàng)建的實(shí)例,將不會(huì)看到這些特定于某個(gè)請(qǐng)求的狀態(tài)變化。當(dāng)處理請(qǐng)求結(jié)束,request作用域的bean實(shí)例將被銷(xiāo)毀。

  Session作用域

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

針對(duì)某個(gè)HTTPSession,Spring容器會(huì)根據(jù)userPreferencesbean定義創(chuàng)建一個(gè)全新的userPreferencesbean實(shí)例,且該userPreferencesbean僅在當(dāng)前HTTPSession內(nèi)有效。與request作用域一樣,你可以根據(jù)需要放心的更改所創(chuàng)建實(shí)例的內(nèi)部狀態(tài),而別的HTTPSession中根據(jù)userPreferences創(chuàng)建的實(shí)例,將不會(huì)看到這些特定于某個(gè)HTTPSession的狀態(tài)變化。當(dāng)HTTPSession最終被廢棄的時(shí)候,在該HTTPSession作用域內(nèi)的bean也會(huì)被廢棄掉。

  global session作用域

<bean id="userPreferences" class="com.foo.UserPreferences" scope="globalSession"/>

global session作用域類(lèi)似于標(biāo)準(zhǔn)的HTTPSession作用域,不過(guò)它僅僅在基于portlet的web應(yīng)用中才有意義。Portlet規(guī)范定義了全局Session的概念,它被所有構(gòu)成某個(gè)portlet web應(yīng)用的各種不同的portlet所共享。在global session作用域中定義的bean被限定于全局portletSession的生命周期范圍內(nèi)。

請(qǐng)注意,假如你在編寫(xiě)一個(gè)標(biāo)準(zhǔn)的基于Servlet的web應(yīng)用,并且定義了一個(gè)或多個(gè)具有global session作用域的bean,系統(tǒng)會(huì)使用標(biāo)準(zhǔn)的HTTPSession作用域,并且不會(huì)引起任何錯(cuò)誤。

  作用域bean與依賴(lài)

能夠在HTTP request或者Session(甚至自定義)作用域中定義bean固然很好,但是Spring IoC容器除了管理對(duì)象(bean)的實(shí)例化,同時(shí)還負(fù)責(zé)協(xié)作者(或者叫依賴(lài))的實(shí)例化。如果你打算將一個(gè)Http request范圍的bean注入到另一個(gè)bean中,那么需要注入一個(gè)AOP代理來(lái)替代被注入的作用域bean。也就是說(shuō),你需要注入一個(gè)代理對(duì)象,該對(duì)象具有與被代理對(duì)象一樣的公共接口,而容器則可以足夠智能的從相關(guān)作用域中(比如一個(gè)HTTP request)獲取到真實(shí)的目標(biāo)對(duì)象,并把方法調(diào)用委派給實(shí)際的對(duì)象。

  注意

<aop:scoped-proxy/>不能和作用域?yàn)?code>singleton或prototype的bean一起使用。為singleton bean創(chuàng)建一個(gè)scoped proxy將拋出BeanCreationException異常。

讓我們看一下將相關(guān)作用域bean作為依賴(lài)的配置,配置并不復(fù)雜(只有一行),但是理解“為何這么做”以及“如何做”是很重要的。

<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"> <aop:scoped-proxy/>     </bean>          <bean id="userService" class="com.foo.SimpleUserService">              <property name="userPreferences" ref="userPreferences"/>      </bean> 

在XML配置文件中,要?jiǎng)?chuàng)建一個(gè)作用域bean的代理,只需要在作用域bean定義里插入一個(gè)<aop:scoped-proxy/>子元素即可(你可能還需要在classpath里包含CGLIB庫(kù),這樣容器就能夠?qū)崿F(xiàn)基于class的代理;還可能要使用基于XSD的配置)。上述XML配置展示了“如何做”,現(xiàn)在討論“為何這么做”。在作用域?yàn)?code>request、session以及globalSession的bean定義里,為什么需要這個(gè)<aop:scoped-proxy/>元素呢?下面我們從去掉<aop:scoped-proxy/>元素的XML配置開(kāi)始說(shuō)起:

<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>  <bean id="userManager" class="com.foo.UserManager">     <property name="userPreferences" ref="userPreferences"/> </bean>

從上述配置中可以很明顯的看到singleton beanuserManager被注入了一個(gè)指向HTTPSession作用域beanuserPreferences的引用。singletonuserManagerbean會(huì)被容器僅實(shí)例化一次,并且其依賴(lài)(userPreferencesbean)也僅被注入一次。這意味著,userManager在理論上只會(huì)操作同一個(gè)userPreferences對(duì)象,即原先被注入的那個(gè)bean。而注入一個(gè)HTTPSession作用域的bean作為依賴(lài),有違我們的初衷。因?yàn)槲覀兿胍闹皇且粋€(gè)userManager對(duì)象,在它進(jìn)入一個(gè)HTTPSession生命周期時(shí),我們希望去使用一個(gè)HTTPSessionuserPreferences對(duì)象。

當(dāng)注入某種類(lèi)型對(duì)象時(shí),該對(duì)象實(shí)現(xiàn)了和UserPreferences類(lèi)一樣的公共接口(即UserPreferences實(shí)例)。并且不論我們底層選擇了何種作用域機(jī)制(HTTP request、Session等等),容器都會(huì)足夠智能的獲取到真正的UserPreferences對(duì)象,因此我們需要將該對(duì)象的代理注入到userManagerbean中, 而userManagerbean并不會(huì)意識(shí)到它所持有的是一個(gè)指向UserPreferences引用的代理。在本例中,當(dāng)UserManager實(shí)例調(diào)用了一個(gè)使用UserPreferences對(duì)象的方法時(shí),實(shí)際調(diào)用的是代理對(duì)象的方法。隨后代理對(duì)象會(huì)從HTTPSession獲取真正的UserPreferences對(duì)象,并將方法調(diào)用委派給獲取到的實(shí)際的UserPreferences對(duì)象。

  自定義作用域

  詳情百度,知道有這么個(gè)東西就行了


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 西城区| 松溪县| 罗定市| 邳州市| 休宁县| 汨罗市| 太仓市| 浦城县| 蓝山县| 潜江市| 枣阳市| 舒兰市| 静安区| 敖汉旗| 永善县| 田东县| 额济纳旗| 余江县| 盐山县| 中山市| 北安市| 古蔺县| 崇文区| 安平县| 盐津县| 合川市| 乌苏市| 本溪| 定襄县| 紫云| 雅安市| 万盛区| 武夷山市| 五莲县| 房产| 夹江县| 钦州市| 清河县| 乌苏市| 保亭| 松江区|