测试代码(Spring Bean默认使用单例模式)
@Autowired
HttpServletRequest request;
@Autowired
HttpServletResponse response;
@GetMapping("/test")
@ResponseBody
public void test() throws IOException {
// return request.getParameter("a");
response.getWriter().println("hello");
response.getWriter().flush();
}
@GetMapping("/test2")
@ResponseBody
public void test2() throws InterruptedException {
TimeUnit.SECONDS.sleep(5);
// int i = 0;
// while (i < 20) {
// TimeUnit.SECONDS.sleep(5);
// System.out.println(request.getParameter("a"));
// i++;
// }
// return request.getParameter("a");
}
结论
成员变量注入的方式不会出现线程安全问题,主要原因是ThreadLocal将线程间的变量进行隔离。获取HttpServletRequest对象的建议使用方式:
- Controller方法入参形式获取;
- 使用以下Util获取:
public final class SpringServletUtil {
public static HttpServletRequest getHttpServletRequest() {
return getServletRequestAttributes().getRequest();
}
public static HttpServletResponse getHttpServletResponse() {
return getServletRequestAttributes().getResponse();
}
public static HttpSession getHttpSession(boolean create) {
return getHttpServletRequest().getSession(create);
}
public static HttpSession getHttpSession() {
return getHttpSession(true);
}
public static ServletContext getServletContext() {
WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
if (webApplicationContext == null) {
return null;
}
return webApplicationContext.getServletContext();
}
private static ServletRequestAttributes getServletRequestAttributes() {
return (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
}
private SpringServletUtil() {
}
}