struts2中action是多例的,即一个session产生一个action。struts 2的Action是多实例的并发单例,也就是每次请求产生一个Action的对象。原因是:struts 2的Action中包含数据,例如你在页面填写的数据就会包含在Action的成员变量里面。如果Action是单实例的话,这些数据在多线程的环境下就会相互影响,例如造成别人填写的数据被你看到了。所以Struts2的Action是多例模式的,
struts2一定要使用多例模式!struts2一定要使用多例模式!struts2一定要使用多例模式!重要的事情说三遍!!!
单独的Struts2框架
1.struts2的Action默认是多实例的并非单例,也就是每次请求产生一个Action的对象,即每次访问的参数都被封装在Action的成员变量中。
2.struts2中Action多实例的优势在于是线程安全的,每次请求都会创建单独的Action类来处理,而不用想servlet一样担心线程安全问题。
struts2和spring整合后
会使用spring的注解管理对象,此时action类对象会进入IOC容器被spring管理
尽管struts2本身Action默认是多例的,但spring的IOC容器默认时单例,此时就矛盾了?
那么内部是如何处理的呢?
Spring管理Struts2的Action自动设置为单例。这样Action的生命周期为服务器生命周期,也就是说不关闭应用服务器,Action一直存在,Action中的属性也一直存在。
这样做的好处:
分页对象所需要的数据对象存在于Action中是不被销毁的,直到页面重新对数据对象输入查询条件.
这样做的缺点:
1) Struts2的Action是单例,其中的FieldError,actionerror中的错误信息会累加,即使再次输入了正确的信息,也过不了验证.
2) Struts2的Action是有状态的,他有自己的成员属性,所以在多线程下,会有线程安全问题,这是最大的问题。
多个线程会共享一个ActionContext和ValueStack,这样并发访问的时候就会出现问题了.例如造成别人填写的数据被你看到了.又例如,两个线程同时提交向同一个Action提前请求参数或在同一个页面上查询信息,会在提交和查询的先后顺序等条件上产生冲突,导致出来一些意外的问题。
解决办法:
方案: 就是不用单例, spring中bean的作用域设为prototype,每个请求对应一个Action实例.(建议这样做)