无法很好地理解 spring-mvc 的“@Autowired HttpServletRequest”
Can't understand `@Autowired HttpServletRequest` of spring-mvc well
在我们的 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()
方法,它都应该 return 相同的值(第一个请求的)。
但是当我尝试的时候,我发现了几个有趣的事情:
- controller 中的
request.hashCode()
总是不同的(如我所料)
RequestService
中的request.hashCode()
总是一样的(和我想的一样)
- 但是如果我用不同的 header
abc
发出请求,header 值是不同的!!!
对于单例 RequestService
,spring 似乎保留了 request
实例,但更改了它包含的 headers!
如何理解?
看看作用域代理。 http://www.java-allandsundry.com/2012/08/spring-scoped-proxy.html
基本上,您注入一个代理,该代理保留对当前 HttpRequest bean 的引用,并为您提供正确的代理,通过请求 ID 选择它。
恕我直言,在 Web 层之外使用 HttpRequest 并不是一个好的做法。我只会在控制器中使用它。
在我们的 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()
方法,它都应该 return 相同的值(第一个请求的)。
但是当我尝试的时候,我发现了几个有趣的事情:
- controller 中的
request.hashCode()
总是不同的(如我所料) RequestService
中的request.hashCode()
总是一样的(和我想的一样)- 但是如果我用不同的 header
abc
发出请求,header 值是不同的!!!
对于单例 RequestService
,spring 似乎保留了 request
实例,但更改了它包含的 headers!
如何理解?
看看作用域代理。 http://www.java-allandsundry.com/2012/08/spring-scoped-proxy.html 基本上,您注入一个代理,该代理保留对当前 HttpRequest bean 的引用,并为您提供正确的代理,通过请求 ID 选择它。
恕我直言,在 Web 层之外使用 HttpRequest 并不是一个好的做法。我只会在控制器中使用它。