Action单例同步
Struts2的Action可以不需实现任何接口或继承任何类,就是一个包含了execute()方法的POJO。
继承com.opensymphony.xwork2.ActionSupport类,并重载execute()方法。
struts2中action是多例的,即一个session产生一个action。
原因是:struts 2的Action中包含数据,例如你在页面填写的数据就会包含在Action的成员变量里面。如果Action是单实例的话,这些数据在多线程的环境下就会相互影响,例如造成别人填写的数据被你看到了。所以Struts2的Action是多例模式的。
==========================================================================
《Struts2单例引起的问题及解决思考》
【http://blog.csdn.net/kebikakaxi/article/details/8120365】
Spring管理Struts2的Action自动设置为单例。这样Action的生命周期为服务器生命周期,也就是说不关闭应用服务器,Action一直存在,Action中的属性也一直存在。
这种现象的好处在于,分页对象所需要的数据对象存在于Action中是不被销毁的,直到页面重新对数据对象输入查询条件。
这样做的缺点在于,一,两个浏览器同时操作一个页面,会在查询等条件的保存上产生冲突,致使A浏览器的查询条件影响到B浏览器的查询结果;二,没有良好设计的系统中,重用Action和多次利用Action的时候无法有效甄别数据的有效性。
因此思考是否可以通过一些办法来解决此类问题。
办法一:设置Action bean的生命周期为Session,即每个浏览器的打开影响着一套Action的生命周期,解决不同用户互相影响的问题;
(通常和spring整合使用的时候,在struts.xml文件要配置一个元素 <constant name="struts.objectFactory" value="spring" /> 或者在struts.property文件中配置 struts.objectFactory = spring 。。。可以在spring的配置文件中的bean元素里用一个scope属性来配置action是用什么生命周期,singleton,prototype,request,session等等)
办法二:通过设置过滤器或者拦截器,或者设置类中的单独属性,判断查询条件是否由理想对象传来,如果不是则销毁值对象,如果是则继承值对象的查询条件。
一些关于拦截器的资料:http://blog.csdn.net/feng_sundy/archive/2007/10/11/1820668.aspx
==========================================================================
《由Spring管理的Struts2的Action的单实例问题》
《Struts2的Action的线程安全问题》
背景 :
1) Struts2 会对每一个请求,产生一个Action的实例来处理.
2) Spring的Ioc容器管理的bean默认是单实例的.
当Struts2与Spring整合后,由spring来管理Struts2的Action,会遇到什么问题 ?如何解决 ?
----------------------------------------------------------------
会遇到什么问题?
Struts2与Spring整合后, 由spring来管理Struts2的Action, bean默认是单实例有情况下,会有如下问题:
1) Action是单例,其中的FieldError,actionerror中的错误信息会累加, 即使再次输入了正确的信息,也过不了验证.
2) Struts2的Action是有状态的,他有自己的成员属性, 所以在多线程下,会有问题.
【所以需要解决多线程同步的问题】
----------------------------------------------------------------
如何解决?
方案一: 就是不用单例, spring中bean的作用域设为prototype,每个请求对应一个实例.(保持多实例模式)
方案二: spring中bean的作用域设为session ,每个session对应一个实例,解决了多线程问题.
再写一个拦截器, 清空 FieldError与actionerror
Java代码
public?class?ClearFieldErrorInterceptor?extends?AbstractInterceptor?{
@Override
public?String?intercept(ActionInvocation?invocation)?throws?Exception?{
ActionSupport?actionSupport?=?(ActionSupport)invocation.getAction();
actionSupport.clearErrorsAndMessages();
String?resultCode?=?invocation.invoke();
return?resultCode;
}
-------------------------------------------------------------------------------------
总结 :
方案一 , bean的作用域设为prototype, 担心性能不好, 但没实际测试过,不好说话,也只是担心而已.
方案二: 由于对方案一有担心, 所有才有了方案二, 不知比方案一性能能高多少
有时间 ,再测试一下.

浙公网安备 33010602011771号