[Spring MVC] HandlerMapping & HandlerAdapter
과거 Spring Controller 인터페이스
org.springframework.web.servlet.mvc.Controller
public interface Controller {
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
Controller
인터페이스는@Controller
와 전혀 다르다.
OldController
@Component("/springmvc/old-controller")
public class OldController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
return null;
}
}
@Component
: 이 컨트롤러는/springmvc/old-controller
라는 이름의 스프링 빈으로 등록되었다.- 빈의 이름으로 URL을 매핑
컨트롤러가 호출되기 위한 조건
- HandlerMapping
- HandlerMapping에서 이 컨트롤러를 찾을 수 있어야 한다.
- Ex) 스프링 빈의 이름으로 핸들러를 찾을 수 있는 핸들러 매핑이 필요.
- HandlerAdapter
- HandlerMapping을 통해 찾은 핸들러를 실행할 수 있는 HandlerAdapter가 필요.
- Ex)
Controller
인터페이스를 실행할 수 있는 핸들러 어댑터를 찾고 실행해야 한다.
HandlerMapping, HandlerAdapter
스프링 부트가 자동 등록하는 HandlerMapping, HandlerAdapter
(일부 생략..)
HandlerMapping
0 = RequestMappingHandlerMapping : 애노테이션 기반의 컨트롤러인 @RequestMapping에서 사용.
1 = BeanNameUrlHandlerMapping : 스프링 빈의 이름으로 핸들러를 찾는다.
HandlerAdapter
0 = RequestMappingHandlerAdapter : 애노테이션 기반의 컨트롤러인 @RequestMapping에서 사용.
1 = HttpRequestHandlerAdapter : HttpRequestHandler 처리
2 = SimpleControllerHandlerAdapter : Controller 인터페이스 (애노테이션X, 과거에 사용)
HandlerMapping, HandlerAdapter가 모두 순서대로 찾고, 만약 없다면 다음 순서로 넘어간다.
1. 핸들러 매핑으로 핸들러 조회
HandlerMapping
을 순서대로 실행해서 핸들러를 찾는다.- 위 경우는 빈 이름으로 핸들러를 찾아야 하기 때문에
BeanNameUrlHandlerMapping
이 실행에 성공하고 핸들러인OldController
를 반환한다.
2. 핸들러 어댑터 조회
HandlerAdapter
의supports()
를 순서대로 호출.SimpleControllerHandlerAdapter
가Controller
인터페이스를 지원하므로 대상이 된다.
3. 핸들러 어댑터 실행
DispatcherServlet
이 조회한SimpleControllerHandlerAdapter
를 실행하면서 핸들러 정보도 함께 넘겨준다.SimpleControllerHandlerAdapter
는 핸들러인OldController
를 내부에서 실행하고, 그 결과를 반환한다.
정리
OldController
를 실행하면서 사용된 객체는 다음과 같다.
HandlerMapping = BeanNameUrlHandlerMapping
HandlerAdapter = SimpleControllerHandlerAdapter
HttpRequestHandler
HttpRequestHandler
는 서블릿과 가장 유사한 형태의 핸들러이다.
HttpRequestHandler
public interface HttpRequestHandler {
void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
MyHttpRequestHandler
@Component("/springmvc/request-handler")
public class MyHttpRequestHandler implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
1. 핸들러 매핑으로 핸들러 조회
HandlerMapping
을 순서대로 실행해서 핸들러 조회.- 빈 이름으로 핸들러를 찾아야 하기 때문에
BeanNameUrlHandlerMapping
이 실행되고, 성공하면 핸들러인MyHttpRequestHandler
를 반환.
2. 핸들러 어댑터 조회
HandlerAdapter
의supports()
를 순서대로 호출.HttpRequestHandlerAdapter
가HttpRequestHandler
인터페이스를 지원하므로 대상이된다.
3. 핸들러 어댑터 실행
DispatcherServlet
이 조회한HttpRequestHandlerAdapter
를 실행하면서 핸들러 정보도 함께 넘겨준다.HttpRequestHandlerAdapter
는 핸들러인MyHttpRequestHandler
를 내부에서 실행하고, 그 결과를 반환한다.
정리
MyHttpRequestHandler
를 실행하면서 사용된 객체는 다음과 같다.
HandlerMapping = BeanNameUrlHandlerMapping
HandlerAdapter = HttpRequestHandlerAdapter
댓글남기기