스프링 MVC 1편 (백엔드 웹 개발 핵심 기술)

Ch06. 스프링 MVC(기본 기능) - 요청 매핑 헨들러 어뎁터 구조

webmaster 2022. 3. 7. 15:19
728x90

SpringMVC 구조

  • 대체 어디서 메시지 컨버터를 처리하는 것인가
    • 모든 비밀은 애노테이션 기반의 컨트롤러, 그러니까 @RequestMapping을 처리하는 핸들러 어댑터인 RequestMappingHandlerAdapter (요청 매핑 헨들러 어뎁터)에 있다.

RequestMappingHandlerAdapter 동작방식

  • ArgumentResolver
    • 애노테이션 기반의 컨트롤러는 매우 다양한 파라미터를 사용할 수 있다.
      • HttpServletRequest , Model 은 물론이고, @RequestParam , @ModelAttribute 같은 애노테이션 그리고 @RequestBody , HttpEntity 같은 HTTP 메시지를 처리하는 부분까지 매우 큰 유연함을 보여주었다
    • 이렇게 파라미터를 유연하게 처리할 수 있는 이유가 바로 ArgumentResolver 덕분이다.
    • 애노테이션 기반 컨트롤러를 처리하는 RequestMappingHandlerAdaptor 는 바로 이 ArgumentResolver를 호출해서 컨트롤러(핸들러)가 필요로 하는 다양한 파라미터의 값(객체)을 생성한다
    • 그리고 이렇게 파리미터의 값이 모두 준비되면 컨트롤러를 호출하면서 값을 넘겨준다.
    • 예)
      • HandlerMethodArgumentResolver
      • ArgumentResolver의 supportsParameter()를 호출해서 해당 파라미터를 지원하는지 체크하고, 지원하면 resolveArgument()를 호출해서 실제 객체를 생성한다. 그리고 이렇게 생성된 객체가 컨트롤러 호출 시 넘어가는 것이다.
    • ReturnValueHandler
      • HandlerMethodReturnValueHandler 를 줄여서 ReturnValueHandle 라 부른다. ArgumentResolver와 비슷한데, 이것은 응답 값을 변환하고 처리한다.
      • 컨트롤러에서 String으로 뷰 이름을 반환해도, 동작하는 이유가 바로 ReturnValueHandler 덕분이다.
      • 스프링은 10여개가 넘는 ReturnValueHandler를 지원한다.
        • 예) ModelAndView , @ResponseBody , HttpEntity , String

HTTP 메시지 컨버터

Http 메시지 컨버터 위치

    • HTTP 메시지 컨버터를 사용하는 @RequestBody 도 컨트롤러가 필요로 하는 파라미터의 값에 사용된다
    • 요청의 경우 @RequestBody 를 처리하는 ArgumentResolver 가 있고, HttpEntity를 처리하는 ArgumentResolver 가 있다. 이 ArgumentResolver들이 HTTP 메시지 컨버터를 사용해서 필요한 객체를 생성하는 것이다.
    • 응답의 경우 @ResponseBody 와 HttpEntity를 처리하는 ReturnValueHandler 가 있다. 그리고 여기에서 HTTP 메시지 컨버터를 호출해서 응답 결과를 만든다.
    • 스프링 MVC는 @RequestBody @ResponseBody 가 있으면 RequestResponseBodyMethodProcessor (ArgumentResolver) HttpEntity 가 있으면 HttpEntityMethodProcessor (ArgumentResolver)를 사용한다
    • 확장
      • 스프링이 필요한 대부분의 기능을 제공하기 때문에 실제 기능을 확장할 일이 많지는 않다.
      • 기능 확장은 WebMvcConfigurer 를 상속받아서 스프링 빈으로 등록하면 된다.
      • 실제 자주 사용하지는 않으니 실제 기능 확장이 필요할 때 WebMvcConfigurer를 검색해보자
      • @Bean
        public WebMvcConfigurer webMvcConfigurer() {
             return new WebMvcConfigurer() {
                 @Override
                 public void addArgumentResolvers(List<HandlerMethodArgumentResolver>
                resolvers) {
                 	//...
                 }
                 @Override
                 public void extendMessageConverters(List<HttpMessageConverter<?>>
                converters) {
                     //...
                 }
             };
        }
728x90