어떻게 하면 핸들러를 애노테이션으로 등록할 수 있는가?
DispatcherServlet 초기화
DispatcherServlet 동작 순서
1. 요청을 분석한다. (로케일, 테마, 멀티파트 등)
2. (핸들러 맵핑에게 위임하여) 요청을 처리할 핸들러를 찾는다.
3. (등록되어 있는 핸들러 어댑터 중에) 해당 핸들러를 실행할 수 있는 “핸들러 어댑터”를 찾는다.
4. 찾아낸 “핸들러 어댑터”를 사용해서 핸들러의 응답을 처리한다.
HandlerMapping
Dispatcher.class
doService -> doDispatch -> mappedHandler = getHandler(processedRequest); (핸들러를 찾아오는 부분)
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
아무런 설정을 하지 않아도 DispatcherServlet이 기본적으로 등록한 BeanNameUrlHandlerMapping, RequestMappingHandlerMapping 두 개의 HandlerMapping이 있다. 실질적으로 RequestMappingHandlerMapping이 애노테이션으로 등록한 컨트롤러와 @RequestMapping, @GetMapping, @PostMapping 등을 사용해 지정한 핸들러를 찾아준다.
그 다음에는 HandlerApapter를 찾는다.
doDispatch -> HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [" + handler +
"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
아무런 설정을 하지 않아도 DispatcherServlet이 기본적으로 등록한 기본 전략인 HttpRequestHandlerAdpater, SimpleControllerHandlerAdpater, RequestMappingHandlerAdapter 세 개의 HandlerAdpater가 있다. 그리고 실질적으로 RequestMappingHandlerAdapter가 핸들러를 실행시키는 HandlerAdapter이다.
doDispatch -> mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
HandlerAdpater를 가져와 요청을 처리한다.
ha.handle(processedRequest, response, mappedHandler.getHandler()); -> RequestMappingHandlerAdpater.class -> handleInternal 메소드 -> mav = invokeHandlerMethod(request, response, handlerMethod); 에서 실제 HandlerMethod를 invoke한다.
그리고 @RestController는 @Controller + @ResponseBody이다. 따라서 응답을 처리할 HandleMethodReturnValueHandler는 RequestResponseBodyMethodProcessor가 된다.
참고