들어가며

  • 저번 포스트에서 우리가 만들었던 프론트 컨트롤러의 역할을 수행하는 Dispatcher Servlet에 대해 알아보았다.
  • 이번 포스트에서는 핸들러 매핑과 핸들러 어댑터에 대해 알아본다.

 

 

과거의 컨트롤러

  • 저 두 파트를 보기 전에 예전에 사용했던 컨트롤러를 한 번 보도록 하자.
  • 과거에는 컨트롤러가 인터페이스 형식이었고 해당 인터페이스를 상속받은 객체를 빈으로 등록하는 형식을 사용하였다.
public interface Controller{
    ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
@Component("/something/old-controller")
public class OldController implements Controller{
    
     @Override
     public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception{
         System.out.println("old-controller");
         return null;
     }
}
  • 구현체를 보면 URL이 컴포넌트에 들어가있다. 컴포넌트 내부의 스트링은 해당 컴포넌트의 이름으로 취급한다.
  • 즉 해당 스프링 빈의 이름이 요청을 처리할 수 있는 URL로 설정된 것이다.
  • 스프링에서 실행해보면 해당 URL로 요청을 보낼 때 정상적으로 출력이 수행되는 것을 알 수 있다.

 

 

 

HandlerMapping, HandlerAdapter

  • 저 컨트롤러는 어떻게 실행될 수 있었을까? 이것에 대한 답을 찾기 위해서 이전에 Dispatcher Servlet이 어떻게 요청을 처리하는지부터 생각해보자.
    • Dispacher Servlet은 /something/old-controller로 되어있는 URL을 받고 해당 URL을 처리할 수 있는 핸들러가 존재하는지를 찾는다.
    • 이후 처리할 수 있는 핸들러를 실행시킬 수 있는 핸들러 어댑터가 존재하는지를 찾는다.
    • 이후 핸들러 어댑터에 해당 핸들러를 넘기면서 실행시킨다.
  • 여기서 HandlerMapping과 HandlerAdapter에 요구되는 것은 다음과 같다.
    • 먼저 빈의 이름으로 핸들러를 찾을 수 있는 HandlerMapping 객체가 필요하다. 왜냐하면 요청을 처리할 수 있는지 없는지를 빈의 이름으로 확인할 수 있도록 했기 때문이다.
    • 이후 찾은 OldController는 Controller 인터페이스를 상속받은 구현체이다. 즉 HandlerAdapter는 Controller 인터페이스를 실행할 수 있는 기능이 존재해야 한다.
  • 지금은 어노테이션을 사용하여 컨트롤러 패턴을 구현한다. 처리 가능한 URL을 표기하는 방법은 @RequestMapping을 사용한다. 따라서 현재 스프링 MVC에서 HandlerMapping은 @RequestMapping을 통해 핸들러를 찾을 수 있게 해야한다.
  • 그리고 당연히 핸들러가 @RequestMapping 기반으로 만들어졌기 때문에, 이 핸들러를 실행할 수 있는 HandlerAdapter도 필요하다.
  • 다행히 스프링은 HandlerMapping과 HandlerAdapter을 대부분 구현체로 구현해 두었다.
  • 스프링 부트가 자동으로 등록하는 핸들러 매핑과 핸들러 어댑터 구현체들을 2~3개 정도 알아보자.
HandlerMapping

0 = RequestMappingHandlerMapping : 어노테이션 기반 @RequestMapping에서 사용
1 = BeanNameUrlHandlerMapping : 스프링 빈의 이름으로 핸들러를 찾는다.

HandlerAdapter

0 = RequestMappingHandlerAdapter : 어노테이션 기반 @RequestMapping에서 사용
1 = HttpRequestHandlerAdapter : HttpRequestHandler 처리
2 = SimpleControllerHandlerAdapter : Controller 인터페이스 처리
  • 위의 0, 1 숫자들은 우선순위이다. 즉 스프링 MVC가 실행된 뒤에 요청이 들어올 때 먼저 RequestMappingHandlerMapping을 사용하여 핸들러를 탐색하고, 찾지 못했다면 BeanNameUrlHandlerMapping을 통해 핸들러를 탐색한다.
    • 만약 그래도 찾지 못하면 추가적으로 존재하는 여러 HandlerMapping구현체들을 우선순위 순으로 적용하여 찾아나간다.
  • 이후 HandlerAdapter도 동일한 방식으로 탐색한다.
복사했습니다!