论坛首页 入门技术论坛

spring源码分析-controller的线程安全

浏览 7840 次
该帖已经被评为新手帖
作者 正文
   发表时间:2010-07-07  
jakoes 写道
  大家都知道,struts1.2由于是线程安全的,每一个请求都去实例化一个action,造成大量并发时的资源浪费。
  struts2在这一点上做了改进,每个action都是一个singleton,所有的请求都是请求同一个action实例。这样在一定程度上能节约资源,但又有安全问题。最常见的就是在action中声明有块状的实例变量,因为这一点是不被提倡的。如果一定要声明,那一定要加上同步块。
 


反了哦
struts2 大部分是每次实例化
struts1 是单粒的
0 请登录后投票
   发表时间:2010-07-07  
别误人子弟,赶紧修改。struts2是多例
0 请登录后投票
   发表时间:2011-06-16  
楼主,误人子弟
0 请登录后投票
   发表时间:2011-06-16   最后修改:2011-06-16
现在的web mvc的请求控制器(action或controller)的实例化有这么三种,一种是作为全局对象的单例方式,第二是全局对象的prototype方式,第三种是局部对象的方式。
在用第一种方式的时候,如果把请求控制器直接暴露给开发者,那么肯定是线程不安全的,也就是说,单例的实例变量,会被多线程共享,造成不安全。所以当把请求控制器直接暴露给开发者时候,避免线程安全的解决方式之一,就是把这个全局的请求控制器设置为prototype,可是会造成额外的开销(要精打细算吗)。
第三种方式把请求的逻辑对象,“插入”到底层的请求控制器里,那个底层的请求控制器不用开发者去关注,类似webWork,因为“插入”的逻辑对象是"局部变量",所以线程安全,不过也会有开销的问题(不用那么精打细算吧)。
具体有下面几种情况:
1.servlet 的实例化是在容器里,是单例,第一种设计方式。
1.struts1的action,都会放在一个map里面管理,单例,第一种设计方式。
2.spring mvc的controller,注入到spring 的bean容器里。是单例,第一种设计方式。
3.webWork早期的版本,是基于ServletDispatcher,是继承HttpServlet,即对servlet的封装。
servlet虽然是单例,ServletDispatcher 本身不会像struts1,spring mvc那样,直接把servlet的封装暴露给开发者,而是让开发者去写好acton,ServletDispatcher 处理services方法时,调用那些acton就行了。这里就不存在servlet的线程安全问题。第三种方式。
3.webWork现在的版本(struts2)。抛弃了ServletDispatcher,而用filterDispatcher,这个filter的封装。而基于filter的封装,因为可以把请求控制器直接当成一个普通的pojo,由filter调用请求控制器(action)进来处理。所以每次处理请求,new 一次 请求控制器,就不会有线程安全的问题。第三种方式。
4.当struts2和spring整合的时候,需要注入action到spring中去,spring默认的实例action的方式是单例,所以这样会有线程安全的问题,因为,struts2的acton里的实例变量,经常是用来接收http请求参数的,所以配置的时候,一定要设置成prototype。第二种设计方式。
5.不过,如果用了struts2-spring 插件的时候,这个插件对action的实例,默认是prototype,不需要设置。第一种设计方式。但是可以设置为prototype。第二种设计方式。

0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics