Deep Dive /Java Web /17-V1

17-V1. Controller → DispatcherServlet: ModelAndView 반환

컨트롤러가 ModelAndView를 반환하면, Spring MVC는 이를 뷰 렌더링 경로로 인식합니다. 오픈소스 기준으로는 InvocableHandlerMethod#doInvoke()가 컨트롤러 반환값을 얻고, ServletInvocableHandlerMethod.invokeAndHandle()가 이를 후속 처리기로 넘깁니다.


이번 단계의 역할 — 반환값이 뷰를 렌더링해야 하는 응답이라는 사실이 확정된다

컨트롤러 반환값이 “뷰를 렌더링해야 하는 응답”이라는 사실이 확정되는 단계입니다.


호출 흐름 요약 — doInvoke() 실행 → ModelAndView 반환 → 처리기로 전달

  1. doInvoke(args)가 컨트롤러 메서드를 실행합니다.
  2. 컨트롤러가 ModelAndView를 반환합니다.
  3. ServletInvocableHandlerMethod.invokeAndHandle()가 반환값 처리기로 넘깁니다.
  4. 이후 DispatcherServlet이 뷰 렌더링 경로를 밟습니다.

호출 흐름 다이어그램 — Controller의 ModelAndView가 뷰 응답 경로로 넘어간다

sequenceDiagram participant Controller participant IHM as InvocableHandlerMethod participant SIHM as ServletInvocableHandlerMethod participant DS as DispatcherServlet Controller-->>IHM: ModelAndView IHM-->>SIHM: returnValue SIHM-->>DS: view response path

핵심 코드 — 같은 doInvoke() 반환값이지만 여기서는 ModelAndView다

// InvocableHandlerMethod.java
Object returnValue = doInvoke(args);
return returnValue;
// ServletInvocableHandlerMethod.java
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
this.returnValueHandlers.handleReturnValue(
        returnValue, getReturnValueType(returnValue), mavContainer, webRequest);

코드 해설 — Spring은 ModelAndView를 뷰 응답 후보로 받아 다음 단계에 넘긴다

ModelAndView 반환 자체는 컨트롤러 코드이지만, Spring은 그 반환값을 하나의 “뷰 응답 후보”로 받아 다음 단계에 넘깁니다.


설계 의도 — 컨트롤러는 뷰 이름과 모델만 정하고 렌더링은 프레임워크가 맡는다

컨트롤러는 뷰 이름과 모델만 결정하고, 실제 렌더링은 프레임워크가 뒤에서 처리하도록 역할을 분리한 구조입니다.


다음 단계 연결 — 17-V2 컨트롤러 직후 postHandle()이 호출되는 장면으로 이어진다

다음 문서 17-V2에서는 컨트롤러 실행 직후 인터셉터의 postHandle()이 어떻게 호출되는지 봅니다.

← 이전: 17. Controller → DispatcherServlet: 응답 분기 시작 | 다음: 17-V2. DispatcherServlet → HandlerInterceptor