Action单例同步

Struts2Action可以不需实现任何接口或继承任何类,就是一个包含了execute()方法的POJO

继承com.opensymphony.xwork2.ActionSupport类,并重载execute()方法。

 

struts2action是多例的,即一个session产生一个action

原因是:struts 2Action中包含数据,例如你在页面填写的数据就会包含在Action的成员变量里面。如果Action是单实例的话,这些数据在多线程的环境下就会相互影响,例如造成别人填写的数据被你看到了。所以Struts2Action是多例模式的。

 

 

==========================================================================

Struts2单例引起的问题及解决思考》

http://blog.csdn.net/kebikakaxi/article/details/8120365

Spring管理Struts2Action自动设置为单例。这样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是用什么生命周期,singletonprototyperequestsession等等
办法二:通过设置过滤器或者拦截器,或者设置类中的单独属性,判断查询条件是否由理想对象传来,如果不是则销毁值对象,如果是则继承值对象的查询条件。 
一些关于拦截器的资料:http://blog.csdn.net/feng_sundy/archive/2007/10/11/1820668.aspx

 

==========================================================================

《由Spring管理的Struts2Action的单实例问题》

Struts2Action的线程安全问题》

背景 :

1) Struts2 会对每一个请求,产生一个Action的实例来处理.

2) SpringIoc容器管理的bean默认是单实例的.

Struts2Spring整合后,spring来管理Struts2Action,会遇到什么问题 ?如何解决 ?

----------------------------------------------------------------

会遇到什么问题?

Struts2Spring整合后spring来管理Struts2Action,  bean默认是单实例有情况下,会有如下问题:

1) Action是单例,其中的FieldError,actionerror中的错误信息会累加即使再次输入了正确的信息,也过不了验证.

2) Struts2Action是有状态的,他有自己的成员属性所以在多线程下,会有问题.

【所以需要解决多线程同步的问题】

----------------------------------------------------------------

如何解决?

方案一就是不用单例, springbean的作用域设为prototype,每个请求对应一个实例.(保持多实例模式)

方案二: springbean的作用域设为session ,每个session对应一个实例,解决了多线程问题.

再写一个拦截器清空 FieldErroractionerror

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, 担心性能不好但没实际测试过,不好说话,也只是担心而已.

方案二由于对方案一有担心所有才有了方案二不知比方案一性能能高多少

有时间 ,再测试一下.

 

posted @ 2015-09-26 22:57  Uncle_Nucky  阅读(393)  评论(0)    收藏  举报