SpringMVC中的Controller是单例模式吗?如果是,为什么其可以支持多线程访问?

SpringMVC中Controller默认情况下是单例模式(可通过@Scope(value="prototype")设置为多例)

先来看一下默认情况下:

@Controller
@RequestMapping(value = "/springTest")
public class SpringMvcController
{
    public Map hashMap = new HashMap();

    @RequestMapping(value="methodA")
    @ResponseBody
    public String methodA(String type) throws InterruptedException
    {
    	hashMap.put("1", "张三");
    	return "success";
    	
    }
    
    @RequestMapping(value="methodB")
    @ResponseBody
    public Map methodB(HttpServletRequest request) throws InterruptedException
    {
    	hashMap.put("2", "李四");
    	hashMap.put("3", "王五");
    	return hashMap;
    	
    }
    
}

我们先请求methodA(),返回"success" ,然后请求methodB()返回结果是:

SpringMVC中的Controller是单例模式吗?如果是,为什么其可以支持多线程访问?_第1张图片

然后设置为多例模式:

@Controller
@RequestMapping(value = "/springTest")
@Scope(value="prototype")
public class SpringMvcController
{
    public Map hashMap = new HashMap();

    @RequestMapping(value="methodA")
    @ResponseBody
    public String methodA(String type) throws InterruptedException
    {
    	hashMap.put("1", "张三");  	
        return "success";
    }
    
    @RequestMapping(value="methodB")
    @ResponseBody
    public Map methodB(HttpServletRequest request) throws InterruptedException
    {
    	hashMap.put("2", "李四");
    	hashMap.put("3", "王五");
    	return hashMap;
    	
    }
    
}

多例模式下先请求methodA(),然后请求methodB()我们看到返回结果是:

SpringMVC中的Controller是单例模式吗?如果是,为什么其可以支持多线程访问?_第2张图片

通过对比发现默认情况下(单例模式)我们多次请求的话,成员变量拿到的是相同的一个(因为请求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方法的类成员属性。执行单例对象的方法不会有线程安全的问题
因为方法是磁盘上的一段代码,每个线程在执行这段代码的时候,会自己去内存申请临时变量

你可能感兴趣的:(Spring)