Thank you for your answers
after my testing and exploration.
concludes that
using @ autowire
to inject HttpServletRequest is thread-safe.
specific verification process I wrote blog
interested can see, if there is anything wrong, please point it out.
thanks again to the programmers upstairs who are eager to answer my questions
fromerr=XhvpvVTi" rel=" nofollow noreferrer "> blog address stamp me
ps: what is discussed above is
when Controller is in singleton mode.
it is thread-safe to write this for the following reasons:
- the request injected into controller is a jdk dynamic proxy object, an instance of ObjectFactoryDelegatingInvocationHandler. When we call the method of the member domain request, we actually call the related method of the getObject () object of objectFactory. The objectFactory here is RequestObjectFactory.
- the getObject of RequestObjectFactory is actually taken from the threadlocal of RequestContextHolder.
- when you first enter the dispatcherServlet of springmvc, the request-related objects will be set to the threadlocal of RequestContextHolder.
reference: injecting Request member domains into SpringMVC Controller
well, I made a fool of myself, preoccupied with solving the secondary request
the same problem every time, and forgot the theme.
add @ ModelAttribute
indeed there will be thread safety problems !
.
if you want to use object properties and deal with thread safety, there is a simple way to deal with thread safety, but is very rough , just use @ Scope ("prototype")
to have Spring MVC generate a new entity class every time you request.
but why does Spring MVC default to singleton? Naturally, because of the performance and overhead advantages of the singleton, writing @ Scope ("prototype")
means giving up the advantage of the singleton.
so it's really a way, but it's not good. I'm sorry to make a fool of you.
@Controller
// @Scope("prototype")
public class AController{
//@Autowired //autowried
protected HttpServletRequest request;
protected HttpServletResponse response;
@ModelAttribute
public void bindRequestObject(HttpServletRequest request, HttpServletResponse response) {
this.request = request;
this.response = response;
}
@RequestMapping("/test")
public Result test(){
System.out.println(request.toString());
request.getHeader("uid");
}
}
1. After Autowire is injected into request, there will be security problems in using instance variables
2, overwriting request
3, same hashcode or an object
feel that it is troublesome to write parameters in the method, so you can:
@Controller
public class AControllre extends AbstractController {
@RequestMapping("/test")
public String test(){
//
String name = getRequest().getParameter("username");
return "";
}
}
class AbstractController {
protected HttpServletRequest getRequest() {
return ((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
}
protected HttpServletResponse getResponse() {
return new ServletWebRequest(((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest()).getResponse();
}
}
I have seen this way of writing for the first time, why not write it this way?
@Controller
public class AController{
@RequestMapping("/test")
public Result test(HttpServletRequest request){
System.out.println(request.toString());
request.getHeader("uid");
}
}
in fact, in most cases, request does not have to be passed as a parameter. For example, if you want to get the uid, in the request header, you can write:
@Controller
public class AController{
@RequestMapping("/test")
public Result test(@RequestHeader("uid") String uid) {
System.out.println(uid); // request.getHeader("uid")
}
}
< hr >
20180613 complements the answer made two years ago:
the above answer does not directly answer the question raised by the subject, so it can be regarded as an incorrect answer. The following supplementary answer:
the way given by the subject is thread-safe! There is no problem with this approach.
httpRequestServlet is not a class attribute, but a thread variable, so I think the best way to use it is to use RequestContextHolder. CurrentRequestAttributes () will pick it up.