[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 = BeanNameUrlHandlerMappingHandlerAdapter = 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 = BeanNameUrlHandlerMappingHandlerAdapter = HttpRequestHandlerAdapter
댓글남기기