SpringMVC或SpringBoot默认是单例模式(Singleton),多个请求是访。。。
SpringMVC Controller默认情况下是Singleton(单例)的,当request过来,不⽤每次创建Controller,会⽤原来的instance去处理。那么当多个线程调⽤它的时候,会不会发⽣线程不安全呢?
1、先说明下 Controller默认情况单例的问题:
使⽤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类不是单例。以下是测试代码:
springmvc常用标签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 28import 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 Parameter("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);
}
}
分别三次请求: localhost:8080/example/test.do?data=15
得到的返回结果如下。
第⼀次: singletonInt=15
第⼆次: singletonInt=30
第三次: singletonInt=45
从以上结果可以得知,singletonInt的状态是共享的,因此Controller是单例的。
2、对别Struts与springmvc对⽐
Struts2 :默认prototype,Struts2 是基于类的,处于线程安全的考虑,采⽤了prototype模式,也就是说每次请求都会新建⼀个类来处理,⾃然就没有线程安全问题了,每次请求的类和数据都是单独的。
Springmvc :默认singleton 单例模式,Springmvc 是基于⽅法的,同⼀个url的请求是同⼀个实例处理的。每次请求都会把请求参数传递到同⼀个⽅法中,此时如果类⾥⾯有成员变量,那么这个变量就不是线程安全的了(例如上⾯的例⼦private int singletonInt=1; 这个变量如果想线程安全则可以⽤ThreadLocal)。
在类中没有成员变量的前提下则是线程安全的。
参考:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论