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