1、问题描述
SpringMVC中获取request对象?若通过注入来引入该对象,即:在controller或者service里面,引入
HttpServletReqeust
,如下:
@Autowire
private HttpServletReqeust request;
会不会导致后面的request覆盖前面的request? 是否存在线程安全问题?
2、测试
@Controller
public class TestRequestHashCodeController {
@RequestMapping("/testRequestHashCode")
@ResponseBody
public Object testRequestHashCode(HttpServletRequest request) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("requestHashCode",request.hashCode());
return jsonObject;
}
}
现象:在浏览器不断按F5发送请求,响应结果为:
1333295416
1159125429
1911632730
...
注:该模块代码已整理并提交至
https://github.com/jiangcaijun/ssm
项目中。
具体位置为
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)。
3、分析与总结
-
线程安全除了同步以外还有一种方式叫做线程级别变量,通过ThreadLocal对象来封装。
-
RequestContextListener在servletContext初始化时为ThreadLoacl配置request对象,FrameworkServlet作为兜底策略,保证所有被DispatcherServlet处理的request在被处理前都被设置到ThreadLocal中;
-
总的来说。spring能够成功得解决request对象的线程安全问题。该问题解决的基础是request对象在线程中单例。然后注入代理对象,该代理对象能够从当前线程的ThreadLocal中获取request对象,并获取方法的执行结果。最后,spring通过Listener和Servlet保证在请求处理前request对象被设置到线程的ThreadLocal中。
4、参考链接
-
SpringMvc学习心得(四)springmvc中request的线程安全问题 – CSDN博客
-
SpringMVC在controller层注入HttpServletRequest – CSDN博客
转载于:https://my.oschina.net/u/3136014/blog/1590499