2015-01-19 22 views
5

Nella nostra applicazione primavera, usiamo HttpServletRequest in due modi:Non riesco a capire `@Autowired HttpServletRequest` della primavera-MVC ben

(il codice qui sono Simplied, e sembra privo di senso)

  1. Nel controllore:

    @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 una componente normale:

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

In un primo momento, stavo pensando che il secondo modo è completamente sbagliato, perché dovrebbe solo iniettare l'istanza request una volta. Quindi, non importa quando invoco il metodo getHeaderAbc(), dovrebbe restituire lo stesso valore (della prima richiesta).

Ma quando ho provato, ho trovato diverse cose interessanti:

  1. Il request.hashCode() controller è sempre diverso (come mi aspettavo)
  2. Il request.hashCode() in RequestService è sempre lo stesso (come pensavo)
  3. Ma il valore dell'intestazione è diverso se invio una richiesta con un'intestazione diversa abc !!!

Sembra per il singleton RequestService, molla mantiene l'istanza request, ma ha cambiato le intestazioni in esso contenuti!

Come capire?

risposta

7

Dai un'occhiata al proxy dell'ambito. http://www.java-allandsundry.com/2012/08/spring-scoped-proxy.html Fondamentalmente si inietta un proxy che mantiene un riferimento agli attuali bean HttpRequest e ti dà quello giusto, selezionandolo dall'ID della richiesta.

L'IMHO che utilizza HttpRequest al di fuori del livello Web non è una buona pratica. Lo userei solo nei controllori.

Problemi correlati