• Oracle教程 数据库优化
  • JAVA
    JAVA教程 java基础 JAVA框架 Spring Spring MVC Struts Struts1 Swing教程 JAVA经验 JAVA面试 多线程面试题 常见JAVA面试题 智力面试题
  • PHP
    PHP教程
  • WEB
    WEB教程 HTML5 Jquery热门插件 前端开发
  • 杂项
    其他 Eclipse 代码库 工具软件 已解决问题 常用系统工具 应用服务器 开源系统 软件测试
  • 热门标签
    多线程 执行计划 职业规划 面试介绍 设计模式 jvm优化 SQL面试 MySql web面试 垃圾收集器 jar打包 xml面试 常见面试题 SQL优化 ant工具 tomcat struts ajax面试 java术语 java排序 java优化 ibatis spring java算法 spring Oracle java集群 java虚拟机 hibernate Oracle DBA

spring mvc 的Controller类默认Scope是单例(singleton)的

By Lee - Last updated: 星期一, 二月 10, 2014 Leave a Comment

使用Spring MVC有一段时间了,之前一直使用Struts2,在struts2中action都是原型(prototype)的, 说是因为线程安全问题,对于Spring MVC中bean默认都是(singleton)单例的,那么用@Controller注解标签注入的Controller类是单例实现的?

测试结果发现spring3中的controller默认是单例的,若是某个controller中有一个私有的变量i,所有请求到同一个controller时,使用的i变量是共用的,即若是某个请求中修改了这个变量a,则,在别的请求中能够读到这个修改的内容。 若是在@Controller之前增加@Scope(“prototype”),就可以改变单例模式为多例模式

以下是测试步骤,代码与结果.

1. 如果是单例类型类的,那么在Controller类中的类变量应该是共享的,如果不共享,就说明Controller类不是单例。以下是测试代码:

 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class ExampleAction {      private int singletonInt= 1 ;       @RequestMapping (value = "/test" )       @ResponseBody       public String singleton(HttpServletRequest request,               HttpServletResponse response) throws Exception {           String data=request.getParameter( "data" );           if (data!= null &&data.length()> 0 ){               try {                int paramInt= Integer.parseInt(data);               singletonInt = singletonInt + paramInt;               }               catch (Exception ex){                   singletonInt+= 10 ;               }           } else {               singletonInt+= 1000 ;           }           return String.valueOf(singletonInt);      } }

分别三次请求: http://localhost:8080/example/test.do?data=15

得到的返回结果如下。

第一次: singletonInt=15

第二次: singletonInt=30

第三次: singletonInt=45

从以上结果可以得知,singletonInt的状态是共享的,因此Controller是单例的。

2. 如果Controller类是单例,那么多个线程请求同一个Controller类中的同一个方法,线程是否会堵塞

 
1 2 3 4 5 6 7 8 9 10 11 12 13 @RequestMapping (value = "/sleepdata" ) @ResponseBody public String switcher(HttpServletRequest request       , HttpServletResponse response)             throws Exception {    String sleep = request.getParameter( "sleep" );    if (sleep.equals( "on" )) {        Thread.currentThread().sleep( 100000 );         return "sleep on" ;     } else {         return sleep;    }

验证方法:分别发送两个请求,

第一个请求:http://localhost:8080/coreplat/sleepdata.do?sleep=on

第二个请求:http://localhost:8080/coreplat/sleepdata.do?sleep=test

验证结果:第一个请求发出去以后,本地服务器等待100s,然后返回结果”sleep on”,在本地服务器等待的者100s当中,发送第二个请求,直接返回结果”test”。说明之间的线程是不互相影响的。

更多推荐

spring MVC中的controller是单例模式,但是是多线程,各个线程之间不影响!