HttpServletRequest利用 autowire 注入,线程安全问题

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、参考链接

猜你喜欢

转载自my.oschina.net/u/3136014/blog/1590499