SPRING

[SPRING] 요청 매핑 헨들러 어댑터

steadyMan 2022. 4. 17. 21:32

HTTP 메시지 컨버터를 사용한 요청, 응답처리에 대해 정리했었는데 이 글은

컨버터를 거치치 않는 파라미터 ex) @ModelAttribute, @RequestParam 등을

어디서 주입을 받으며 다양한 리턴타입은 어디서 유기적으로 처리되는지 또 스프링MVC의 요청, 응답처리의

어느 시점에서 메세지 컨버터가 사용되는 건지 정리하였습니다.

 

개인적인 학습의 정리글입니다. 

 

스프링MVC 흐름

@RequestMapping을 처리하는 핸들러 어댑터인 RequestMappingHandlerAdapter을 보면 처리과정을 확인할 수 있다. 

 

RequestMappingHandlerAdapter

애노테이션 기반의 컨트롤러는 다양한 파라미터를 사용할 수 있는데

HttpServletRequest, Model, @Requestparam, @ModelAttribute 같은 애노테이션은 물론

@RequestBody, HttpEntity 같은 HTTP 메시지를 처리하는 부분까지 매우 큰 유연함을 가진다. 

 

이렇게 파라미터의 유연한 처리를 가능하게 하는 것이 Argument Resolver이다. 

 

애노테이션 기반의 컨트롤러를 처리하는 RequestMappingHandlerAdaptor는 바로 ArgumentResolver를 호출해서 

컨트롤러가 필요로 하는 파라미터(메소드에 선언된 객체)를 생성한다. 그리고 파라미터가 준비되면 컨트롤러를 호출하면서 값을 넘겨준다. 

 

스프링은 다양한 ArgumentResolver를 제공하는데 그 리스트는 공식 홈페이지에서 확인 가능하다. 

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is more com

docs.spring.io

ArgumentResolver 동작방식 

HandlerMethodArgumentResolver을 줄여서 ArgumentResolver라 한다. 

supportsParameter()를 호출하여 파라미터를 지원하는지 체크하고, 지원하면 resolveArgument()를 호출하여 실제 객체를 생성한다. 이렇게 생성된 객체가 컨트롤러 호출 시 전달되는 것이다. 

ReturnValueHandle 동작방식 

HandlerMethodReturnValueHandler 를 줄여서 ReturnValueHandler라 부르며

ArgumentResolver와 유사하며 응답 값을 변환하고 처리한다. 

 

컨트롤러에서 리턴타입에 따라 다르게 동작하는 것도 ReturnValueHandler 때문이다. 

 

스프링은 ReturnValueHandler역시 다양하게 제공하며 공식 홈페이지에서 확인 가능하다. 

ex) HttpEntity<>, ResponseEntity, String, @ReponseBody

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is more com

docs.spring.io

HTTP 메시지 컨버터

그렇다면 HTTP 메시지 컨버터는 어디에서 호출되는 걸까? 

요청의 경우

@RequestBody, HttpEntity를 각각 처리하는 ArgumentResolver가 있다 이 ArgumentResolver들이 

HTTP 메시지 컨버터를 사용하여 필요한 객체를 생성한다.

HttpEntityMethodProcessor를 보면 

readWithMessageConverters()에서 바디를 리턴 받는 걸 볼 수 있는데 

 

readWithMessageConverters()의 로직을 보면 

HttpMessageConverter를 반복구문 처리하여 동작하는 걸 확인할 수 있다. 

응답의 경우

@ResponseBody, HttpEntity를 처리하는 ReturnValueHandler가 있고 여기서 HTTP 메세지 컨버터를 호출하여

응답 결과를 만든다. 

확장

스프링은 아래의 객체 모두 인터페이스로 제공하기 때문에 필요하면 언제든지 기능을 확장할 수 있다. 

  • HandlerMethodArgumentResolver
  • HandlerMethodReturnValueHandler
  • HttpMessageConverter

정리

HTTP와 관련된 애노테이션, 객체를 제외한 모든 컨트롤러 메소드 파라미터는

ArgumentResolver, ReturnValueHandler에서 처리되며 HTTP와 연관된 객체는 HTTP 메세지 컨버터를

호출하여 처리한다.