Can't understand `@Autowired HttpServletReques

2019-03-29 23:05发布

In our spring application, we use HttpServletRequest in two ways:

(the code here are simplied, and seems meaningless)

  1. In the controller:

    @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);
    }
    
  2. In a normal component:

    @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");
        }
    }
    

At first, I was thinking the 2nd way is totally wrong, because it should only inject the request instance once. So no matter when I invoke getHeaderAbc() method, it should return the same value(of the first request).

But when I try it, I found several interesting things:

  1. The request.hashCode() in controller is always different (as I expected)
  2. The request.hashCode() in RequestService is always the same (as I thought)
  3. But the header value is different if I issue a request with a different header abc !!!

It seems for the singleton RequestService, spring keeps the request instance, but changed the headers it contains!

How to understand it?

1条回答
ら.Afraid
2楼-- · 2019-03-29 23:53

Take a look at the scoped proxy. http://www.java-allandsundry.com/2012/08/spring-scoped-proxy.html Basically you inject a proxy that keeps a references to the current HttpRequest beans and gives you the right one, selecting it by the request id.

IMHO using HttpRequest outside of the web layer is not a good practice. I would use it only in the controlellrs.

查看更多
登录 后发表回答