首先对于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配置文件中找。

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

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

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

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

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

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

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

  4. Springmvc 并发访问的线程安全性问题

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

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

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

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

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

  7. Spring 中的 bean线程安全性分析

    首先:Spring 中的 bean不是线程安全的 Spring容器中的Bean是否线程安全,容器本身并没有提供Bean的线程安全策略,因此可以说Spring容器中的Bean本身不具备线程安全的特性,但 ...

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

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

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

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

随机推荐

  1. Itunes制作手机铃声,图文版

    一.下载歌曲,选择歌曲用itunes打开,打开出现下面界面 二.设置歌曲 右键点击歌曲,找到显示简介,点击选项,截取音乐,出现下图: 截取你喜欢的部分,点击确定 点击确定后,选中该歌曲,找到左上方 文 ...

  2. 【Android Developers Training】 100. 使用Intent修改联系人数据

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  3. Exameple014实现html中checkbox的全选,反选和全不选(1)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 全选与单选chekbox的自定义实现(angular框架)

    2017年7月4日,我原本可以像其他同时一样早点回家,玩几把王者荣耀,但是我没有,因为我选择留下来,写一篇博客. 项目中经常性的会遇到什么点击"全选"按钮,勾中所有"单选 ...

  5. Unity3D-Shader-实现X光效果

    [旧博客转移 - 2016年1月3日 16:40 ] 最近学习了一些Shader效果,打算把学到的知识总结一下,这篇讲一下这种轮廓发光的效果(如下图所示),也有一些地方管这个叫X光     1.原理 ...

  6. Spring ContentNegotiatingViewResolver

    1. Spring 返回视图采用了ViewResolver,如果一般是jsp的话,可以采用InternalResourceViewResolver. 2.还可以通过ContentNegotiating ...

  7. [NOIP2013/Codevs3287]货车运输-最小[大]生成树-树上倍增

    Problem 树上倍增 题目大意 给出一个图,给出若干个点对u,v,求u,v的一条路径,该路径上最小的边权值最大. Solution 看到这个题第一反应是图论.. 然而,任意路径最小的边权值最大,如 ...

  8. Bash : 索引数组

    Bash 提供了两种类型的数组,分别是索引数组(indexed array)和关联数组(associative array).本文主要介绍索引数组的基本用法. 索引数组的基本特点 Bash 提供的数组 ...

  9. 论Activity及启动模式,Fragment,Service的使用以及生命周期

    Activity: 这是我总结出来的,介于Activity生命周期相对较多,我在Google官方的生命周期图上又加了几个常用的,便于大家理解 对于ACtivity,先说说启动模式(ps:复制党去死吧, ...

  10. Oracle 10gR2分析函数

    Oracle 10gR2分析函数汇总 (Translated By caizhuoyi 2008‐9‐19) 说明:  1. 原文中底色为黄的部分翻译存在商榷之处,请大家踊跃提意见:  2. 原文中淡 ...