2015-01-19 29 views
5

W naszej aplikacji wiosny, używamy HttpServletRequest na dwa sposoby:nie mogę zrozumieć `@Autowired HttpServletRequest` of spring-mvc dobrze

(kod tutaj są simplied i wydaje się bez znaczenia)

  1. W regulatorze:

    @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. w normalnym części:

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

Początkowo myślałem, że druga droga jest całkowicie błędna, ponieważ powinna jednorazowo wtłaczać instancję request. Niezależnie od tego, kiedy wywołuję metodę getHeaderAbc(), powinna ona zwracać tę samą wartość (pierwszego żądania).

Ale gdy próbuję go, znalazłem kilka ciekawych rzeczy:

  1. request.hashCode() w sterowniku jest zawsze inny (jak się spodziewałem)
  2. request.hashCode() w RequestService jest zawsze taka sama (jak myślałem)
  3. Ale wartość nagłówka jest inna, jeśli zgłoszę żądanie z innym nagłówkiem abc !!!

Wydaje do Singleton RequestService, sprężyna utrzymuje instancji request, ale zmienił nagłówki nim zawarte!

Jak to zrozumieć?

Odpowiedz

7

Spójrz na zakresowe proxy. http://www.java-allandsundry.com/2012/08/spring-scoped-proxy.html Zasadniczo wstrzykujesz serwer proxy, który przechowuje odniesienia do bieżących komponentów bean HttpRequest, i podaje właściwy, wybierając go za pomocą identyfikatora żądania.

IMHO przy użyciu HttpRequest poza warstwą WWW nie jest dobrą praktyką. Używałbym go tylko w kontrolerach.