在写springMVC的Control中有不少这种代码, 如须要获取request对象去作某些事情java
如:spring
@Controller @RequestMapping(value = "/user") public class LoanActionPage extends AbstractAction { @RequestMapping(value = "/page/active") public String loanAaccountActivePage(HttpServletRequest request) { // get request to dosomething String pathInfo = request.getPathInfo(); return "active"; } }
貌似每次要写个control时都得把request当住参数来传,非常冗余。安全
其实能够在control里定义一个request对象,注入,而后随时用多线程
如:app
public class AbstractAction { @Autowired protected HttpServletRequest request; ... ...
而后在control中直接用:spa
@Controller @RequestMapping(value = "/user") public class LoanActionPage extends AbstractAction { @RequestMapping(value = "/page/active") public String loanAaccountActivePage() { // get request to dosomething String pathInfo = request.getPathInfo(); return "active"; } }
那么问题来了,sevlet是多线程的,每次请求的request实际上是个新的对象,这样直接共享引用,是否会形成线程不安全呢?线程
方便了,问题也来了,servelt实际上是多线程,共享一个request是否会有安全问题呢,分析下spring的代码code
发现是注入实际上是往WebApplicationContextUtils经过RequestObjectFactory拿值,跟踪对象
返回的是RequestContextHolder里的值. 追踪RequestContextHolderget
每次返回的实际上是, RequestAttributes的实现类ServletWebRequest(ServletRequestAttributes)里的request. 由于RequestAttributes是属于threadLocal的,因此注入的request也是线程安全的了
HttpServlet实现类 FrameworkServlet-> service()->processRequst()
每次请求都会往里面设置最新的request, 设值