SpringMVC中的Controller是單例模式嗎?如果是,爲什麼其可以支持多線程訪問?

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方法的類成員屬性。執行單例對象的方法不會有線程安全的問題
因爲方法是磁盤上的一段代碼,每個線程在執行這段代碼的時候,會自己去內存申請臨時變量

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章