在我们的spring应用程序中,我们以两种方式使用HttpServletRequest
:
(这里的代码简洁,似乎毫无意义)
在控制器中:
@RequestMapping(value = "/hello", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> hello(HttpServletRequest request) {
System.out.println("## controller req.hashcode: " + request.hashCode());
System.out.println("## header 'abc': " + request.getHeader("abc"));
return new ResponseEntity<String>("OK", HttpStatus.OK);
}
在正常组件中:
@Component
class RequestService {
private final HttpServletRequest request;
@Autowired
public RequestService(HttpServletRequest request) {
this.request = request;
}
public String getHeaderAbc() {
System.out.println("## service req.hashcode: " + request.hashCode());
return this.request.getHeader("abc");
}
}
起初,我认为第二种方式是完全错误的,因为它应该只注入一次request
实例。因此,无论何时调用getHeaderAbc()
方法,它都应返回相同的值(第一个请求)。
但是当我尝试它时,我发现了几件有趣的事情:
request.hashCode()
始终不同(正如我所料)request.hashCode()
中的RequestService
始终相同(我认为)abc
!!! 对于单例RequestService
,spring保留request
实例,但更改了它包含的标题!
如何理解?
答案 0 :(得分:8)
看一下范围代理。 http://www.java-allandsundry.com/2012/08/spring-scoped-proxy.html 基本上,您注入一个代理,该代理保留对当前HttpRequest bean的引用,并为您提供正确的代理,并按请求ID选择它。
恕我直言,在网络层之外使用HttpRequest不是一个好习惯。我只会在控制者中使用它。