SpringMVC中Controller默认情况下是单例模式(可通过@Scope(value="prototype")设置为多例)
先来看一下默认情况下:
@Controller
@RequestMapping(value = "/springTest")
public class SpringMvcController
{
public Map<String,Object> hashMap = new HashMap<String,Object>();
@RequestMapping(value="methodA")
@ResponseBody
public String methodA(String type) throws InterruptedException
{
hashMap.put("1", "张三");
return "success";
}
@RequestMapping(value="methodB")
@ResponseBody
public Map<String,Object> methodB(HttpServletRequest request) throws InterruptedException
{
hashMap.put("2", "李四");
hashMap.put("3", "王五");
return hashMap;
}
}
我们先请求methodA(),返回"success" ,然后请求methodB()返回结果是:
然后设置为多例模式:
@Controller
@RequestMapping(value = "/springTest")
@Scope(value="prototype")
public class SpringMvcController
{
public Map<String,Object> hashMap = new HashMap<String,Object>();
@RequestMapping(value="methodA")
@ResponseBody
public String methodA(String type) throws InterruptedException
{
hashMap.put("1", "张三");
return "success";
}
@RequestMapping(value="methodB")
@ResponseBody
public Map<String,Object> methodB(HttpServletRequest request) throws InterruptedException
{
hashMap.put("2", "李四");
hashMap.put("3", "王五");
return hashMap;
}
}
多例模式下先请求methodA(),然后请求methodB()我们看到返回结果是:
通过对比发现默认情况下(单例模式)我们多次请求的话,成员变量拿到的是相同的一个(因为请求methodB时,在methodA中put()进去的值也返回了),而多例模式下拿到的是不同的变量(返回的仅仅是methodB()中put()进去的值)。
那么如果多个线程请求同一个Controller类中的同一个方法,线程是否会堵塞呢?
我们分别发送两次请求到methodA():
http://127.0.0.1:8080/auth/springTest/methodA?type=1
http://127.0.0.1:8080/auth/springTest/methodA?type=2
@Controller
@RequestMapping(value = "/springTest")
public class SpringMvcController
{
@RequestMapping(value="methodA")
@ResponseBody
public String methodA(String type) throws InterruptedException
{
if(type.equals("1"))
{
TimeUnit.SECONDS.sleep(60);//设置等待60秒
return type;
}else
{
return type;
}
}
}
在type等于1时设置方法等待60秒后再饭后,在这60秒内我们发送第二次请求,得到结果是:2
说明两次请求的线程之间并没有影响。
那么SpringMVC默认不是单例模式吗,为什么没有影响呢?
1、spring单例模式是指,在内存中只实例化一个类的对象
2、类的变量有线程安全的问题,就是有get和set方法的类成员属性。执行单例对象的方法不会有线程安全的问题
因为方法是磁盘上的一段代码,每个线程在执行这段代码的时候,会自己去内存申请临时变量