프레임워크(Framework)/Spring

[Spring MVC] 스프링 MVC 핸들러 매핑과 핸들러 어댑터

잇트루 2022. 11. 12. 22:24
반응형
본 내용은 온라인 강의 사이트 인프런의 김영한 님의 강의 내용이 포함되어 있습니다.
'스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술'
 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., -

www.inflearn.com

 

Intro

핸들러 매핑과 핸들러 어댑터는 현재 사용하는 기능은 아니다.

하지만, 과거에 주로 사용했던 컨트롤러로 MVC 패턴의 핸들러 매핑과 어댑터를 이해할 수 있다.

 

Controller 인터페이스

@Controller 어노테이션과는 전혀 다른 스프링 MVC가 제공하는 Controller 인터페이스이다.

옛 버전의 스프링 컨트롤러

org.springframework.web.servlet.mvc.Controller

public interface Controller {

	ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;

}

스프링도 처음에는 이러한 인터페이스를 통해 컨트롤러를 제공했다.

 

컨트롤러 인터페이스를 간단하게 구현하면 다음과 같이 구현할 수 있다.

OldController.java

// 스프링 빈의 이름을 url 패턴으로
@Component("/springmvc/old-controller")
public class OldController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("OldController.handleRequest");
        return null;
    }
}

@Component 어노테이션을 통해 /springmvc/old-controller라는 이름의 스프링 빈으로 등록되어 있다. 이는 빈 이름으로 URL을 매핑하기 위한 것이다.

 

해당 컨트롤러가 호출하기 위해서는 HandlerMapping(핸들러 매핑)과 HandlerAdapter(핸들러 어댑터)가 필요하다.

HandlerMapping

  • 핸들러 매핑에서 해당 해당 컨트롤러를 찾을 수 있어야 한다.
  • 즉, 스프링 빈의 이름으로 핸들러를 찾을 수 있는 핸들러 매핑이 필요한 것이다.

 

HandlerAdapter

  • 핸들러 매핑을 통해 찾은 핸들러를 실행하기 위한 핸들러 어댑터이다.
  • Controller 인터페이스를 실행할 수 있는 핸들러 어댑터를 찾고 실행해야 한다.

 

스프링은 이미 필요한 핸들러 매핑과 어댑터를 대부분 구현되어 있다.

따라서 핸들러 매핑과 어댑터를 직접 만드는 일은 거의 없다.

 

스프링 부트가 자동 등록하는 핸들러 매핑과 핸들러 어댑터는 다양한 형태로 작성할 수 있다.

HandlerMapping

// 어노테이션 기반의 컨트롤러인 @RequestMapping에서 사용
0 = RequestMappingHandlerMapping

// 스프링 빈의 이름으로 핸들러를 찾는다.
1 = BeanNameUrlHandlerMapping
...

 

HandlerAdapter

// 어노테이션 기반의 컨트롤러인 @RequestMapping에서 사용
0 = RequestMappingHandlerAdapter

// HttpRequestHandler 처리
1 = HttpRequestHandlerAdapter

// Controller 인터페이스 처리 (@Controller X)
2 = SimpleControllerHandlerAdapter
...

이 외에도 스프링 부트가 자동으로 등록하는 핸들러 매핑과 핸들러 어댑터는 더 많다.

 

스프링 부트의 컨트롤러를 실행하기 위한 순서

아래와 같은 컨트롤러 인터페이스의 구현체를 실행한다고 가정한다.

OldController.java

@Component("/springmvc/old-controller")
public class OldController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("OldController.handleRequest");
        return null;
    }
}
  1. 핸들러 매핑으로 핸들러 조회
    • 빈 이름으로 찾아주는 BeanNameUrlHandlerMapping 실행 후 OldController 반환
  2. 핸들러 어댑터 조회
    • HandlerAdapter의 supports()를 순서대로 호출
    • SimpleControllerHandlerAdapter가 Controller 인터페이스를 지원하므로 대상이 됨
  3. 핸들러 어댑터 실행
    • DispatcherServlet이 조회한 SimpleControllerHandlerAdapter 실행 후 Handler 정보도 함께 넘김
    • SimpleControllerHandlerAdapter는 OlderController를 내부에서 실행하고 그 결과를 반환

 

핸들러 매핑과 핸들러 어댑터의 우선순위

가장 우선순위가 높은 핸들러 매핑과 핸들러 어댑터는 RequestMappingHandlerMapping, RequestMappingHandlerAdapter이다.

@RequestMapping 어노테이션의 전용 핸들러와 어댑터로 가장 많은 기능을 제공하기도 한다.

반응형