HttpServletRequest利用 autowire 注入,線程安全問題

一、問題描述

SpringMVC中獲取request對象?若經過注入來引入該對象,即:在controller或者service裏面,引入HttpServletReqeust,以下:java

@Autowire
private HttpServletReqeust request;

會不會致使後面的request覆蓋前面的request? 是否存在線程安全問題?git

二、測試

@Controller
public class TestRequestHashCodeController {
    
    @RequestMapping("/testRequestHashCode")
    @ResponseBody
    public Object testRequestHashCode(HttpServletRequest request) {
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("requestHashCode",request.hashCode());
        return jsonObject;
    }
}

現象:在瀏覽器不斷按F5發送請求,響應結果爲:github

1333295416                             
1159125429     
1911632730
...

注:該模塊代碼已整理並提交至https://github.com/jiangcaijun/ssm 項目中。spring

具體位置爲 https://github.com/jiangcaijun/ssm/blob/master/src/main/java/com/ssm/controller/IndexController.java 中的 testRequestHashCode 方法(相對路徑爲: ssm/src/main/java/com/ssm/controller/IndexController.java)。json

三、分析與總結

  • 線程安全除了同步之外還有一種方式叫作線程級別變量,經過ThreadLocal對象來封裝。瀏覽器

  • RequestContextListener在servletContext初始化時爲ThreadLoacl配置request對象,FrameworkServlet做爲兜底策略,保證全部被DispatcherServlet處理的request在被處理前都被設置到ThreadLocal中;安全

  • 總的來講。spring可以成功得解決request對象的線程安全問題。該問題解決的基礎是request對象在線程中單例。而後注入代理對象,該代理對象可以從當前線程的ThreadLocal中獲取request對象,並獲取方法的執行結果。最後,spring經過Listener和Servlet保證在請求處理前request對象被設置到線程的ThreadLocal中。mvc

四、參考連接

相關文章
相關標籤/搜索