spring整合struts2时作用域scope解析
http://zhangjq5.iteye.com/blog/1928165
一、起因:
??????? struts2單獨使用時,action實例的生成是由struts2框架負(fù)責(zé)的,而且實例是基于請求的,每次請求都會產(chǎn)生不同的action實例,這也使得struts2能夠在多線程并發(fā)操作時仍可以安全穩(wěn)定的運行。也是struts2與servlet和struts1的一個很大不同。而spring中bean實例默認(rèn)是單例的,如果將struts2的action交由spring負(fù)責(zé)生成,默認(rèn)情況下action是單例的,在并發(fā)情況下就很可能會引起數(shù)據(jù)混亂的情況(除非action改為無狀態(tài)的,沒有實例變量)。
?
二、現(xiàn)實應(yīng)用:
?????? 平常編程中服務(wù)端常采用用action、service和dao結(jié)構(gòu)的面向接口式編程,service和dao層由于是無狀態(tài)的,所以常采用單例的模式(節(jié)省資源\、提高效率);而action由于常用來與前端頁面進(jìn)行參數(shù)傳遞(action的實例變量),同時會面向前端多個客戶端,為防止并發(fā)導(dǎo)致數(shù)據(jù)錯亂,常采用非單例模式。
?
三、引用網(wǎng)上資料:
??????? (1)、singleton作用域
當(dāng)一個bean的作用域設(shè)置為singleton, 那么Spring IOC容器中只會存在一個共享的bean實例,并且所有對bean的請求,只要id與該bean定義相匹配,則只會返回bean的同一實例。換言之,當(dāng)把一個bean定義設(shè)置為singleton作用域時,Spring IOC容器只會創(chuàng)建該bean定義的唯一實例。這個單一實例會被存儲到單例緩存(singleton cache)中,并且所有針對該bean的后續(xù)請求和引用都將返回被緩存的對象實例,這里要注意的是singleton作用域和GOF設(shè)計模式中的單例是完全不同的,單例設(shè)計模式表示一個ClassLoader中只有一個class存在,而這里的singleton則表示一個容器對應(yīng)一個bean,也就是說當(dāng)一個bean被標(biāo)識為singleton時候,spring的IOC容器中只會存在一個該bean。
配置實例:
<bean id="role" class="spring.chapter2.maryGame.Role" scope="singleton"/>?
或者
<bean id="role" class="spring.chapter2.maryGame.Role" singleton="true"/>
??????? (2)、prototype
prototype作用域部署的bean,每一次請求(將其注入到另一個bean中,或者以程序的方式調(diào)用容器的getBean()方法)都會產(chǎn)生一個新的bean實例,相當(dāng)與一個new的操作,對于prototype作用域的bean,有一點非常重要,那就是Spring不能對一個prototype bean的整個生命周期負(fù)責(zé),容器在初始化、配置、裝飾或者是裝配完一個prototype實例后,將它交給客戶端,隨后就對該prototype實例不聞不問了。不管何種作用域,容器都會調(diào)用所有對象的初始化生命周期回調(diào)方法,而對prototype而言,任何配置好的析構(gòu)生命周期回調(diào)方法都將不會被調(diào)用。清除prototype作用域的對象并釋放任何prototype bean所持有的昂貴資源,都是客戶端代碼的職責(zé)。(讓Spring容器釋放被singleton作用域bean占用資源的一種可行方式是,通過使用bean的后置處理器,該處理器持有要被清除的bean的引用。)
配置實例:
<bean id="role" class="spring.chapter2.maryGame.Role" scope="prototype"/>
或者
<beanid="role" class="spring.chapter2.maryGame.Role" singleton="false"/>
??????? (3)、request?
request表示該針對每一次HTTP請求都會產(chǎn)生一個新的bean,同時該bean僅在當(dāng)前HTTP request內(nèi)有效,配置實例:
request、session、global session使用的時候首先要在初始化web的web.xml中做如下配置:
如果你使用的是Servlet 2.4及以上的web容器,那么你僅需要在web應(yīng)用的XML聲明文件web.xml中增加下述ContextListener即可:
<web-app>
...
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
...
</web-app>
,如果是Servlet2.4以前的web容器,那么你要使用一個javax.servlet.Filter的實現(xiàn):
<web-app>
..
<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>
...
</web-app>
接著既可以配置bean的作用域了:
<bean id="role" class="spring.chapter2.maryGame.Role" scope="request"/>
??????? (4)、session
session作用域表示該針對每一次HTTP請求都會產(chǎn)生一個新的bean,同時該bean僅在當(dāng)前HTTP session內(nèi)有效,配置實例:
配置實例:
和request配置實例的前提一樣,配置好web啟動文件就可以如下配置:
<bean id="role" class="spring.chapter2.maryGame.Role" scope="session"/>
??????? (5)、global session
global session作用域類似于標(biāo)準(zhǔn)的HTTP Session作用域,不過它僅僅在基于portlet的web應(yīng)用中才有意義。Portlet規(guī)范定義了全局Session的概念,它被所有構(gòu)成某個portlet web應(yīng)用的各種不同的portlet所共享。在global session作用域中定義的bean被限定于全局portlet Session的生命周期范圍內(nèi)。如果你在web中使用global session作用域來標(biāo)識bean,那么web會自動當(dāng)成session類型來使用。
配置實例:
和request配置實例的前提一樣,配置好web啟動文件就可以如下配置:
<bean id="role" class="spring.chapter2.maryGame.Role" scope="global session"/>
?
4、spring的作用域:
?????? 為了區(qū)別以上情況,spring對bean元素提供了scope屬性,spring2.0以前只提供了singleton(單例)、non-singleton(也稱prototype)兩種模式,prototype每次訪問都會產(chǎn)生新的對象。spring2.0以后又增加了request、session和global session三個作用域,這三個作用域只針對web應(yīng)用,而且使用方法也有所不同(后面使用方法做詳解)。prototype與request在每次訪問時都會產(chǎn)生不同的實例,區(qū)別在于request只能在web應(yīng)用中使用并且需要額外配置,prototype不限使用場景。session和global session區(qū)別在于global session僅僅在基于portlet的web應(yīng)用中才有意義,如果你在web中使用global session作用域來標(biāo)識bean,那么web會自動當(dāng)成session類型來使用。
?
5、使用方法:
??????? 如引用材料中所訴。不過有幾點是需要注意的,(1)spring的版本,如果要使用request、session和global session,則需要spring2.0以上的版本;(2)web容器的版本,2.4版本對應(yīng)java1.4,2.5版本對應(yīng)java5.0……最終體現(xiàn)在web.xml中,以下是2.5版本:
<web-app version="2.5"
?xmlns="http://java.sun.com/xml/ns/javaee"
?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
?xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
?http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
(3)spring配置文件中的版本,以下是spring2.0,不加版本號有時候會啟動不了:
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
(4)session作用域需要后臺服務(wù)器的維護(hù)session狀態(tài),效率可能會低。
?
總結(jié)
以上是生活随笔為你收集整理的spring整合struts2时作用域scope解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: struts bean static
- 下一篇: 从struts2拦截器到自定义拦截器