WEB BE Repo/Spring

Spring Web MVC가 요청을 처리하는 과정 - DispatcherServlet의 동작구조

조금씩 차근차근 2025. 4. 22. 18:20

DispatcherServlet의 doDispatch() 동작구조

  • DispatcherServlet 구조
    • 라이브러리 : org.springframework.web.servlet.DispatcherServlet
    • DispatcherServlet도 부모 클래스에서 HttpServlet을 상속받아서 사용하고, 서블릿으로 동작한다.
      • DispatcherServlet → FrameworkServlet → HttpServletBean → HttpServlet
    • 스프링 부트는 DispatcherServlet 을 서블릿으로 자동으로 등록하면서 모든 경로( urlPatterns="/" )에 대해서 매핑한다.
      • 참고: 더 자세한 경로가 우선순위가 높다. 그래서 기존에 등록한 서블릿도 함께 동작한다
  • 요청 흐름
    • 서블릿이 호출되면 HttpServlet 이 제공하는 serivce() 가 호출된다.
    • 스프링 MVC는 DispatcherServlet 의 부모인 FrameworkServlet 에서 service() 를 오버라이드 해 두었다.
    • FrameworkServlet.service() 를 시작으로 여러 메서드가 호출되면서 DispatcherServlet.doDispatch() 가 호출된다.
  1. 핸들러 조회: 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러(컨트롤러)를 조회한다.
  2. 핸들러 어댑터 조회: 핸들러를 실행할 수 있는 핸들러 어댑터를 조회한다.
  3. 핸들러 어댑터 실행: 핸들러 어댑터를 실행한다.
  4. 핸들러 실행: 핸들러 어댑터가 실제 핸들러를 실행한다.
  5. ModelAndView 반환: 핸들러 어댑터는 핸들러가 반환하는 정보를 ModelAndView로 변환해서 반환한다.
  6. viewResolver 호출: 뷰 리졸버를 찾고 실행한다.
    • JSP의 경우: InternalResourceViewResolver 가 자동 등록되고, 사용된다.
  7. View 반환: 뷰 리졸버는 뷰의 논리 이름을 물리 이름으로 바꾸고, 렌더링 역할을 담당하는 뷰 객체를 반환한다.
    • JSP의 경우 InternalResourceView(JstlView) 를 반환하는데, 내부에 forward() 로직이 있다.
  8. 뷰 렌더링: 뷰를 통해서 뷰를 렌더링 한다.

실제 doDispatch()를 유사하게 구현한 소스코드

핸들러 매핑과 핸들러 어댑터

  • 핸들러 매핑 방식의 우선순위
    1. RequestMappingHandlerMapping
      • 애노테이션 기반의 컨트롤러인 @RequestMapping에서 사용
      • 해당 어노테이션으로 URI와 매핑된 컴포넌트가 있는지 탐색
    2. BeanNameUrlHandlerMapping
      • 스프링 빈의 이름으로 핸들러를 탐색
      • 스프링 빈의 이름이 URI 와 매핑된 컴포넌트가 있는지 탐색
    • 빈의 이름으로도 핸들러를 탐색하는구나
  • 핸들러 어댑터는 이미 정의된 걸 사용한다.
    • 핸들러 어댑터 종류(탐색 우선순위)
      1. RequestMappingHandlerAdapter
        • 애노테이션 기반의 컨트롤러인 @RequestMapping에서 사용
      2. HttpRequestHandlerAdapter
        • HttpRequestHandler 객체를 처리하는 어댑터
        • 서블릿과 가장 유사한 형태의 핸들러 객체(HttpRequestHandler)들을 처리한다.
      3. SimpleControllerHandlerAdapter
        • Controller 인터페이스(과거에 사용, 애노테이션 X)를 처리하는 어댑터
  • 주어진 Url 패턴에 맞추어 해당 우선순위에 따라 핸들러를 각 맵에서 찾고
    • 해당 핸들러를 사용할 수 있는 핸들러 어댑터도 우선순위에 따라 찾는다.
      • HandlerAdapter 인터페이스의 support() 함수 호출
  • 지금은 죄다 @RequestMapping 사용한다.

뷰 리졸버

  • 뷰 리졸버 설정
    • application.properties에
      • spring.mvc.view.prefix=/WEB-INF/views/
      • spring.mvc.view.suffix=.jsp

뷰 리졸버의 동작 방식에 집중해서 다시 보길 바란다.

  • ModelView를 반환받은 디스패치 서블릿은, 모델 뷰 안의 viewName을 적절하게 바꾸기 위해 viewResolver를 호출한다.
    • 이때, 자동으로 등록되는 뷰 리졸버는 두가지가 있다
      • BeanNameViewResolver
        • 빈 이름으로 뷰를 찾아서 반환
        • 예) 엑셀 파일 생성 기능에 사용
      • InternalResourceViewResolver
        • JSP를 처리할 수 있는 뷰를 반환.
        • JSP처럼 forward() 를 호출해서 처리할 수 있는 경우에 사용
        • 실제로 JSP 페이지 링크에 자주 쓰이는 뷰 리졸버
  • 뷰 리졸버는 해당 viewName 의 앞과 뒤에 설정으로 지정한 문자열을 설정하고 리턴한다.

참고
InternalResourceViewResolver 는 만약 JSTL 라이브러리가 있으면 InternalResourceView 를 상속받은 JstlView 를 반환한다. JstlView 는 JSTL 태그 사용시 약간의 부가 기능이 추가된다.

참고
다른 뷰는 실제 뷰를 렌더링하지만, JSP의 경우 forward() 통해서 해당 JSP로 이동(실행)해야 렌더링이 된다.
JSP를 제외한 나머지 뷰 템플릿들은 forward() 과정 없이 바로 렌더링 된다.

참고
Thymeleaf 뷰 템플릿을 사용하면 ThymeleafViewResolver 를 등록해야 한다. 최근에는 라이브러리만 추가하면 스프링 부트가 이런 작업도 모두 자동화해준다.

 

 

참고 자료 : 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 강의 | 김영한 - 인프런

김영한 | , 원리를 알아야 핵심이 보인다!김영한의 스프링 MVC 기본편 👨‍💻 📌 수강 전 확인해주세요! 본 강의는 자바 스프링 완전 정복 시리즈의 네 번째 강의입니다. 우아한형제들 최연소

www.inflearn.com