作者:俏君woo_267 | 来源:互联网 | 2023-05-26 10:31
在我们的spring应用程序中,我们HttpServletRequest
以两种方式使用:
(这里的代码简洁,似乎毫无意义)
在控制器中:
@RequestMapping(value = "/hello", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity hello(HttpServletRequest request) {
System.out.println("## controller req.hashcode: " + request.hashCode());
System.out.println("## header 'abc': " + request.getHeader("abc"));
return new ResponseEntity("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
实例,但更改了它包含的标题!
怎么理解呢?
1> Evgeni Dimit..:
看一下范围代理.http://www.java-allandsundry.com/2012/08/spring-scoped-proxy.html
基本上你注入了一个代理,它保留对当前HttpRequest bean的引用,并为你提供正确的代理,通过请求id选择它.
恕我直言,在Web层之外使用HttpRequest不是一个好习惯.我只会在控制者中使用它.