在我们的 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()
方法,它应该返回相同的值(第一个请求的值)。
但当我尝试时,我发现了一些有趣的事情:
- The
request.hashCode()
控制器中总是不同的(如我所料)
- The
request.hashCode()
in RequestService
总是一样的(正如我所想的)
- 但是如果我发出具有不同标头的请求,标头值会不同
abc
!!!
看来对于单身人士来说RequestService
,弹簧保持request
实例,但更改了它包含的标头!
怎么理解呢?
查看作用域代理。http://www.java-allandsundry.com/2012/08/spring-scoped-proxy.html http://www.java-allandsundry.com/2012/08/spring-scoped-proxy.html基本上,您注入一个代理,该代理保留对当前 HttpRequest bean 的引用,并为您提供正确的代理,通过请求 id 选择它。
恕我直言,在 Web 层之外使用 Http 请求并不是一个好的做法。我只会在控制器中使用它。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)