@Controller
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "hello";
}
}
디스패처스블릿으로 요청받음
DsipatcherServlet 클래스에서 doDispatch 메소드 실행
HttpServletRequest processedRequest = request; // 요청 받음
mappedHandler = this.getHandler(processedRequest); // handler 얻음
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler()); // handler adaptor 얻음
mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // handler 실행
ha.handle 메소드는 AbstractHandlerMethodAdaper 클래스에 있다
그리고 이 메소드는 RequestMappingHandlerAdapter 클래스의 handleInternal 메소드를 실행한다
invokeHandlerMethod 메소드 실행하면서 getModelAndView 메소드 실행
ModelMap model = mavContainer.getModel();
ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
모델을 만들고 뷰이름을 가져와서 리턴한다
그러면 위 처럼 mv 가 모델과 뷰가 담겨있는 변수인데 이거을 가지고
this.processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
화면 렌더링을 위한 처리작업을 한다
this.render(mv, request, response);
뷰를 선택하는 역할
View view;
if (viewName != null) {
view = this.resolveViewName(viewName, mv.getModelInternal(), locale, request);
if (view == null) {
String var10002 = mv.getViewName();
throw new ServletException("Could not resolve view with name '" + var10002 + "' in servlet with name '" + this.getServletName() + "'");
}
}
아래 메소드를 따라가보자
view = this.resolveViewName(viewName, mv.getModelInternal(), locale, request);
그러면 resolveViewNameInternal 메소드가 실행된다
private View resolveViewNameInternal(String viewName, Locale locale) throws Exception {
if (this.viewResolvers != null) {
for(ViewResolver viewResolver : this.viewResolvers) {
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
}
return null;
}
viewResolver 가 선택되고 적합한 viewResolver 가 최종뷰를 선택해서 리턴한다