Spring MVC 구조 알아보기

su dong·2023년 7월 1일
0

Spring MVC도 프론트컨트롤러 패턴으로 구현되어 있다.
Spring MVC의 프론트컨트롤러가 바로 DispatcherServlet이다.
이 DispatcherServlet이 Spring MVC에서 가장 핵심이 된다.

DispatcherServlet 등록

DispatcherServlet은 부모 클래스에서 HttpServlet을 상속받는다.
DispatcherServlet -> FrameworkServlet -> HttpServletBean -> HttpServlet

스프링부트는 DispatcherSerlvet을 자동으로 등록하면서 모든 경로(urlPatterns = "/*")에 대해서 매핑한다.
단, 더 자세한 경로가 우선순위가 더 높습니다. 그래서 기존에 등록한 servlet도 함게 동작합니다.

요청흐름

Servlet이 호출이 되면 Servlet이 제공하는 service()가 호출된다.
DispatcherServlet은 부모인 FrameworkServlet에 가보면 service()를 오버라이드 해놓았다.
FramworkServlet.service()를 시작으로 여러 매서드가 호출되면서 최종적으로 DispatcherSerlvet.doDispatcher()가 실행된다.

doDispatcher

  1. 핸들러 조회
    getHandler
  2. 핸들러 어뎁터 조회
    getHandlerAdapter(handler)
  3. 핸들러 어뎁터 실행 -> 핸들러 어뎁터를 통해 핸들러 실행 -> ModelAndView반환
    mv = handler(handle)
  4. 뷰 리졸버로 뷰 찾기 -> View반환
  5. 뷰 렌더링
    view.render
protected void doDispatch(HttpServletRequest request, HttpServletResponse
response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
ModelAndView mv = null;
// 1. 핸들러 조회
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 2. 핸들러 어댑터 조회 - 핸들러를 처리할 수 있는 어댑터
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 3. 핸들러 어댑터 실행 -> 4. 핸들러 어댑터를 통해 핸들러 실행 -> 5. ModelAndView 반환
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
processDispatchResult(processedRequest, response, mappedHandler, mv,
dispatchException);
}
private void processDispatchResult(HttpServletRequest request,
HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView
mv, Exception exception) throws Exception {
// 뷰 렌더링 호출
render(mv, request, response);
}
protected void render(ModelAndView mv, HttpServletRequest request,
HttpServletResponse response) throws Exception {
View view;
String viewName = mv.getViewName();
// 6. 뷰 리졸버를 통해서 뷰 찾기, 7. View 반환
view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
// 8. 뷰 렌더링
view.render(mv.getModelInternal(), request, response);
}

DispatcherServlet의 장점

DispatcherServlet의 코드 변경 없이, 원하는 기능을 변경하거나 확장할 수 있다. 대부분의 기능을 인터페이스로 제공하기 때문에, 인터페이스만 구현하면 나만의 컨트롤러를 만들 수 있다.

주요 인터페이스 목록

  • 헨들러 매핑(org.springframework.web.servlet.HandlerMapping)
  • 핸들러 어뎁터(org.springframework.web.servlet.HandlerAdapter)
  • 뷰 리졸버(org.springframework.web.servlet.ViewResolver)
  • 뷰(org.springframework.web.servlet.View)
profile
사람들을 돕는 문제 해결사, 개발자 sudong입니다. 반갑습니다. tkddlsqkr21@gmail.com

0개의 댓글