首先对于spring的IOC来说,对象是由Spring来帮我们管理,也就是在Spring启动的时候,在Spring容器中,由Spring给我们创建的,Spring会帮我们维护,一般都是单例的,也就是一个对象。

spring生成对象默认是单例的。通过scope属性可以更改为多例。

第一部分:验证Spring生成对象默认是单例的。

下面我们来一个网上的例子验证一下:

  1. <bean id="singleton" class="java.util.Date" scope="singleton"></bean>
  2. <bean id="prototype" class="java.util.Date" scope="prototype"></bean>
  1. package test;
  2. import java.util.Date;
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5. import com.opensymphony.xwork2.ActionContext;
  6. public class TestScope {
  7. public static void main(String[] args) {
  8. ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext-web.xml");
  9. Date s1=(Date)context.getBean("singleton");
  10. Date p1=(Date)context.getBean("prototype");
  11. Date s2=(Date)context.getBean("singleton");
  12. Date p2=(Date)context.getBean("prototype");
  13. System.out.println("单例:"+(s1==s2));
  14. System.out.println("非单例:"+(p1==p2));
  15. }
  16. }

输出结果:

结果

单例:true

非单例:false

注:复合数据类型的“== ”对比的是内存中存放的地址,所以此处我们采用“==”去对比

因为object中的equals初始行为是比较内存中的地址,但在一些类库中被覆盖掉了如(String,Integer,Date等)

第二部分:SpringMVC和Struts2中是并发访问否会存在线程安全问题。

对于使用过SpringMVC和Struts2的人来说,大家都知道SpringMVC是基于方法的拦截,而Struts2是基于类的拦截。

对于Struts2来说,因为每次处理一个请求,struts就会实例化一个对象;这样就不会有线程安全的问题了;

而Spring的controller默认是Singleton的,这意味着每一个request过来,系统都会用原有的instance去处理,这样导致两个结果:

一是我们不用每次创建Controller,二是减少了对象创建和垃圾收集的时间;由于只有一个Controller的instance,当多个线程调用它的时候,它里面的instance变量就不是线程安全的了,会发生窜数据的问题。

当然大多数情况下,我们根本不需要考虑线程安全的问题,比如dao,service等,除非在bean中声明了实例变量。因此,我们在使用spring mvc 的contrller时,应避免在controller中定义实例变量。 
如:

  1. public class Controller extends AbstractCommandController {
  2. protected Company company;
  3. protected ModelAndView handle(HttpServletRequest request,HttpServletResponse response,Object command,BindException errors) throws Exception {
  4. company = ................;
  5. }
  6. }

解决方案:

有几种解决方法:
1、在Controller中使用ThreadLocal变量
2、在spring配置文件Controller中声明 scope="prototype",每次都创建新的controller
所在在使用spring开发web 时要注意,默认Controller、Dao、Service都是单例的。

例如:

  1. @Controller
  2. @RequestMapping("/fui")
  3. public class FuiController extends SpringController {
  4. //这么定义的话就是单例
  5. @Controller
  6. @Scope("prototype")
  7. @RequestMapping("/fui")
  8. public class FuiController extends SpringController {
  9. //每次都创建

第三部分:springMVC与struts2的区别。

下面是从网络上摘抄的一段对比,大家可以看看

点击打开链接

1. 机制:spring mvc的入口是servlet,而struts2是filter,这样就导致了二者的机制不同。

2.
性能:spring会稍微比struts快。spring
mvc是基于方法的设计,而sturts是基于类,每次发一次请求都会实例一个action,每个action都会被注入属性,而spring基于方法,粒度更细,但要小心把握像在servlet控制数据一样。spring3
mvc是方法级别的拦截,拦截到方法后根据参数上的注解,把request数据注入进去,在spring3
mvc中,一个方法对应一个request上下文。而struts2框架是类级别的拦截,每次来了请求就创建一个Action,然后调用setter
getter方法把request中的数据注入;struts2实际上是通过setter
getter方法与request打交道的;struts2中,一个Action对象对应一个request上下文。

3. 参数传递:struts是在接受参数的时候,可以用属性来接受参数,这就说明参数是让多个方法共享的。

4. 设计思想上:struts更加符合oop的编程思想, spring就比较谨慎,在servlet上扩展。

5.
intercepter的实现机制:struts有以自己的interceptor机制,spring
mvc用的是独立的AOP方式。这样导致struts的配置文件量还是比spring
mvc大,虽然struts的配置能继承,所以我觉得论使用上来讲,spring mvc使用更加简洁,开发效率Spring
MVC确实比struts2高。spring mvc是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上spring3
mvc就容易实现restful url。struts2是类级别的拦截,一个类对应一个request上下文;实现restful
url要费劲,因为struts2
action的一个方法可以对应一个url;而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。spring3
mvc的方法之间基本上独立的,独享request
response数据,请求数据通过参数获取,处理结果通过ModelMap交回给框架方法之间不共享变量,而struts2搞的就比较乱,虽然方法之间也是独立的,但其所有Action变量是共享的,这不会影响程序运行,却给我们编码,读程序时带来麻烦。

6. 另外,spring3 mvc的验证也是一个亮点,支持JSR303,处理ajax的请求更是方便,只需一个注解@ResponseBody ,然后直接返回响应文本即可。

总结:

这样也说明了SpringMVC还有Servlet都是方法的线程安全,所以在类方法声明的私有或者公有变量不是线程安全的,而struts2的确实是线程安全的。

第四部分:那么对于Struts2+Spring来管理注入的时候呢?

Struts2它是多实例的,对于每个请求都会生成1个实例,spring默认是单实例的(下面针对Struts与Spring集成的两种方式分别来介绍struts2和spring的两种整合方式

一:对于无Spring插件(Struts2-spring-plugin-XXX.jar)的整合方式,需要在spring的action Bean中加业务逻辑控制器类配scope="prototype"。

  1. <bean id="user" class="modle.User" scope="prototype"></bean>

二:对于有Spring插件(Struts2-spring-plugin-XXX.jar)的整合方式:反编译StrutsSpringObjectFactory以及相关的代码才发现,如果在struts
action的配置文件中<action name=".."
class=".."/>中class写的如果是完整的包名和类名的话就是struts创建action对象,也就是多实例的;

总结:如果是spring配置文件中的
bean的名字的话就是spring创建,那么单实例还是多实例就由spring的action
Bean中的业务逻辑控制器类是否配置为scope=”prototype”,有就是多实例的,没有就是单实例的,顺序是先从spring中找,找不到再从struts配置文件中找。

转自 :http://blog.csdn.net/hejingyuan6/article/details/50363647

Springmvc 并发访问的线程安全性问题的更多相关文章

  1. Spring并发访问的线程安全性问题

    Spring并发访问的线程安全性问题 http://windows9834.blog.163.com/blog/static/27345004201391045539953/ 由于Spring MVC ...

  2. (转)Spring并发访问的线程安全性问题(高度总结)

    下面的记录对spring中并发的总结.理论分析参考Spring中Singleton模式的线程安全,建议先看 spring中的并发访问题: 我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下 ...

  3. Spring 并发访问的线程安全性问题

    首先对于spring的IOC来说,对象是由Spring来帮我们管理,也就是在Spring启动的时候,在Spring容器中,由Spring给我们创建的,Spring会帮我们维护,一般都是单例的,也就是一 ...

  4. Spring 是如何解决并发访问的线程安全性问题的

    springmvc的controller是singleton的(非线程安全的),这也许就是他和struts2的区别吧!和Struts一样,Spring的Controller默认是Singleton的, ...

  5. Servlet, Struts2和SpringMVC 并发访问线程安全问题

    第一部分: Servlet不是线程安全的. 要解释Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的. 当Tomcat接收到Client的HTTP ...

  6. 【Java并发.2】线程安全性

    要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享(Shared)和可变的(Mutable)状态的访问. “共享”意味着变量可以由多个线程同时访问,而“可变”则意味着变量的值在其生 ...

  7. Java并发编程 (四) 线程安全性

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.线程安全性-原子性-atomic-1 1.线程安全性 定义: 当某个线程访问某个类时,不管运行时环境 ...

  8. JAVA并发编程之线程安全性

    1.一个对象是否是线程安全的,取决于它是否被多个线程访问.想要使得线程安全,需要通过同步机制来协同对对象可变状态的访问. 2.修复多线程访问可变状态变量出现的错误:1.程序间不共享状态变量 2.状态变 ...

  9. Semaphore可以控制并发访问的线程个数

    public class SemaphoreTest { //信号量,只允许 3个线程同时访问 ); public static void main(String[] args) { Executor ...

随机推荐

  1. ping、traceroute原理

    说明:忘记从哪里拉的博文了,感谢! ping 用类型码为0的ICMP发请 求,受到请求的主机则用类型码为8的ICMP回应. ping程序来计算间隔时间,并计算有多少个包被送达.用户就可以判断网络大致的 ...

  2. 正确显示textarea中输入的回车和空格

    在textarea中输入的文本.如果含有回车或空格.在界面上显示的时候则不那么正常.回车消失了,空格变短了. 如何解决这个问题呢.有2种方法. 1.使用<pre>标签 w3c对pre元素是 ...

  3. ts中interface与class的区别

    interface -- 接口只声明成员方法,不做实现. class -- 类声明并实现方法. 那么接口有什么用呢?设想如下需求: 要实现一个print函数,它将传入的对象打印出来.在实际实现上,它将 ...

  4. git和github新手安装使用教程(三步入门)

    git和github新手安装使用教程(三步入门) 对于新手来说,每次更换设备时,github的安装和配置都会耗费大量时间.主要原因是每次安装时都只关心了[怎么做],而忘记了记住[为什么].本文从操作的 ...

  5. Mysql:执行source sql脚本时,出现:error 2

    Centos下部署mysql: 1.yum -y install mysql*; 2.service mysqld start; 3.chkconfig mysqld on; 4.设置用户名和密码:m ...

  6. C语言中处理结构体的原理

    汇编中有几种寻址方式,分别是直接寻址:(ds:[idata]).寄存器间接寻址(ds:[bx]).寄存器相对寻址(ds:[bx + idata].ds:[bx + si])基址变址寻址(ds:[bx ...

  7. AI时代:推荐引擎正在塑造人类

    We shape our tools and afterwards our tools shape us. ------Marshall McLuhan 麦克卢汉说:"我们塑造了工具,反过来 ...

  8. Swagger入门教程

    [译]5.41 Swagger tutorial 单击此处查看原文 更多概念参见:Implementing Swagger with your API docs 关于 Swagger Swagger能 ...

  9. DAY4-打卡第四天-2018-1-12

    刚经历C语言考试,提前一个小时交卷出来在学一点咯!! 字符串不是一个基本类型,不能用恒等== 而应该用: 变量名.equals(""); 变量名.equalsIgnoreCase( ...

  10. 转- 在ubuntu下安装Nginx

    一. 安装包安装 1.1 安装Nginx $sudo apt-get install nginx Ubuntu安装之后的文件结构大致为: 所有的配置文件都在/etc/nginx下,并且每个虚拟主机已经 ...