Spring MVC에서 HTTP 요청이 어떻게 처리되는지 정리했다.
HTTP 요청을 처리하는 핵심이다.
위 흐름을 코드로 따라가고 싶으면 DispatcherServlet.class의 doDispatch 메서드를 보면 된다.
package org.springframework.web.servlet;
public class DispatcherServlet extends FrameworkServlet {
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
//... HTTP 요청 처리
}
}
핸들러(컨트롤러)를 찾아준다.
public interface HandlerMapping {
@Nullable
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}
핸들러(컨트롤러)의 종류에 따라 HTTP 요청을 처리할 수 있도록 적절한 처리를 해준다.
public interface HandlerAdapter {
// 핸들러(컨트롤러)를 지원하는 어댑터인지 확인한다.
boolean supports(Object handler);
// 핸들러(컨트롤러)가 HttpServletRequest를 처리할 수 있도록 적절한 변환을 해준 후 핸들러에게 넘겨준다.
@Nullable
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}
핸들러(컨트롤러)가 처리할 수 있는 파라미터를 만들어준다.
public interface HandlerMethodArgumentResolver {
// 핸들러의 파라미터를 이 ArgumetResolver가 처리할 수 있는지 확인한다.
boolean supportsParameter(MethodParameter parameter);
// 핸들러에게 넘겨줄 파라미터를 만들어준다.
@Nullable
Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
}
핸들러(컨트롤러)가 돌려주는 return 값을 처리한다.
public interface HandlerMethodReturnValueHandler {
// 핸들러의 return을 이 ReturnValueHandler가 처리할 수 있는지 확인한다.
boolean supportsReturnType(MethodParameter returnType);
// 핸들러의 return을 처리한다.
void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;
}
View를 가져온다.
public interface ViewResolver {
// view 이름으로 View를 가져온다.
@Nullable
View resolveViewName(String viewName, Locale locale) throws Exception;
}
View를 그려서 HTTP 응답을 돌려준다.
public interface View {
// View를 데이터를 사용해서 그린후 HTTP 응답으로 돌려준다.
void render(@Nullable Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
throws Exception;
}
위에 나온 기능들이 DispatcherServlet의 doDispatcher에서 모두 사용된다.
doDispatcher의 흐름을 타고 가면 MVC의 흐름을 파악할 수 있다.
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
//...
// 핸들러(컨트롤러)를 조회한다.
mappedHandler = getHandler(processedRequest);
// 핸들러 어댑터를 조회힌다.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 핸들러 어댑터로 핸들러를 실행한다.
// 이 안에서 HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler가 동작한다.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// 핸들러가 돌려주는 ModelAndView를 처리한다.
// 이안에서 ViewResolver, View가 동작한다.
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
//...
}