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

本文深入探讨了SpringMVC中Controller的单例与多例模式,通过实例对比展示了不同模式下成员变量的行为差异,并分析了线程安全性问题。揭示了即使在单例模式下,方法调用如何保持线程安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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方法的类成员属性。执行单例对象的方法不会有线程安全的问题
因为方法是磁盘上的一段代码,每个线程在执行这段代码的时候,会自己去内存申请临时变量

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值