MVC - DispatcherServlet 1

this-is-spear·2023년 2월 27일
0

스프링 기초부터

목록 보기
2/3
post-thumbnail

Intro

Spring MVC 내부 동작과 최신 버전에서 사용하는 라이브러리를 이해하기 위해서 Spring Docs를 정독했습니다.

이번 포스팅은 Spring Docs에 적힌 DispathcerServlet과 알고 있던 DispathcerServlet를 연결짓는 과정을 정리했습니다.

학습했던 내용

DispatcherServlet

Front controller

스프링 MVC도 프론트 컨트롤러 패턴으로 구현되어 있고, 프론트 컨트롤러가 바로 디스패처 서블릿(DispatcherServlet)이다.

front controller에서 여러 페이지에 걸쳐 탐색 명령을 제어하는 것이 각 페이지에게 탐색 명령을 할당하는 것보다 훨씬 쉽기 떄문에 web app의 workflow에서 자주 사용된다.

URL mapping

스프링 부트는 DispatcherServlet을 서블릿으로 자동 등록하면서 모든 경로(urlPatterns="/)에 대해서 매핑한다.

request은 DispatcherServlet을 통과하기 때문에 serlvetPath 값이 항상 비어있다.

DispatcherServletConfiguration

  • DispatcherServletConfiguration 안에서 DispatcherServlet을 스프링 빈으로 설정한다.

DispatcherServlet은 등록될 떄, HandlerMapping, HandlerAdapter, HandlerExceptionResolver, ViewResolver, LocaleResolver,LocaleContextResolver, ThemeResolver, MultipartResolver, FlashMapManager 등의 bean 정보를 포함한다.

Extended FrameworkServlet

DispatcherServlet 은 FrameworkServlet을 상속받아 만들어진 구현체다.

FrameworkServlet 은 HttpServletBean을 상속받았고, HttpServletBean은 HttpServlet을 상속받아 만들어진 인터페이스다.

DispatcherServlet 요청 흐름

FrameworkServlet.service()를 시작으로 여러 메서드가 호출되면서 DispatcherServlet.doDispatch() 메서드가 호출이 된다.

doDispatch() 동작

  1. mapped handler 조회
  2. handler adapter 조회
  3. mapped handler에서 찾은 pre-processing 실행
  4. model and view 반환
  5. view name을 이용해 view resolver를 찾고, view 렌더링
  6. mapped handler에서 찾은 post-processing 실행

Spring Docs

DispathcerServlet

DispathcerServlet은 front controller pattern을 활용해 request processing을 공유하는 기능을 한다. 즉, DispathcerServlet은 request mapping, view resolution, exception handling 기능을 위해 위임할 component를 찾는다.

Spring Boot Auto-configuration을 이용해 servlet-based web application을 쉽게 구축할 수 있다.

Spring MVC Auto-configuration

Spring Boot는 Spring MVC에 대한 자동 구성을 제공한다. 스프링 기본 기능 외 다음 기능을 제공한다.

  • ContentNegotiatingViewResolverBeanNameViewResolver의 bean 제공
  • Converter, GenericConverter, and Formatter bean 자동 설정
  • MessageCodesResolver 자동 설정
  • ConfigurableWebBindingInitializer 자동 설정
  • WebJars 지원과 정적 리소스 제공 지원
  • HttpMessageConverters 지원
  • 정적 index.html 지원

Context Hierarchy

DispathcerServlet은 Spring Configuration 정보를 파악하기 위해 WebApplicationContex 정보를 요구한다.

WebApplicationContex

  • WebApplicationContextServletContext에 바인딩되어 Servlet에 대한 정보를 가진다.

Root WebApplicationContext

  • Root WebApplicationContext는 여러 개의 DispathcerServlet을 구성하고 각 DispathcerServlet은 자신만의 WebApplicationContext을 가진다.
  • Root WebApplicationContext는 여러 Servlet 인스턴스에서 공유하는 데이터 저장소 및 비즈니스 서비스 같은 bean을 포함한다.

Special Beans Types

  • special bean이란 Spring에 의해 관리되는 인스턴스 중 Spring Contracts를 구현한 객체를 말한다.
  • DispathcerServlet은 요청을 special bean에게 위임해 처리하도록 시키고 적절한 응답을 준비한다.
  • special bean 들은 내장된 contract를 제공하지만, customizing해 확장하거나 교체할 수 있다.

DispathcerServlet에서 감지하는 special bean 목록

Bean typeExplanation
HandlerMappingpre-processing 과 post-processing 를 위한 인터셉터 목록을 매핑한다.
HandlerAdapterDispatcherServlet가 매핑된 핸들러를 호출하도록 돕는다.
HandlerExceptionResolverexceptions을 해결하기 위한 전략을 선택한다.
ViewResolverView 응답을 위해 logical String-based view names을 확인한다.
LocaleResolver, LocaleContextResolverclient 가 사용하는 시간대를 확인한다.
ThemeResolver개인화된 레이아웃을 제공한다.
MultipartResolvermulti-part Request의 구문을 분석한다.
FlashMapManager리다이렉션을 통해 다른 요청으로 attribute를 전달하는 데 사용하는입력과 출력을 관리한다.

Web MVC Conifg

  • 요청을 처리하는 데 필요한 special bean의 하위 클래스를 선언할 수 있다.
  • DispatcherServlet은 각 special bean을 찾기 위해 WebApplicationContext을 확인한다. 일치하는 bean이 없다면 DispatcherServlet.properties에서 나열된 순대로 설정한다.

Servlet Config

  • Servlet 환경에서는 Servlet Container로만 구성하거나 web.xml과 함께 사용할 수 있다.

AbstractDispatcherServletInitializer

  • AbstractDispatcherServletInitializerDispatcherServlet를 재정의하여 DispatcherServlet을 훨씬 더 쉽게 등록할 수 있도록 한다.
  • Java 와 XML 기반으로 Configuration을 만들 때도 AbstractDispatcherServletInitializer를 이용해 구현한다.

Processing

DispatcherServlet에서 요청 처리 동작

  • 요청에서 여러 elements가 사용할 수 있는 attribute로 사용하기 위해 WebApplicationContext에서 검색하고 바인딩한다.
  • 상황에 따라 요청을 처리할 때, 사용할 locale을 확인할 수 있도록 locale resolver를 요청에 바인딩한다.
  • View와 같은 element를 사용할 때, theme을 결정할 수 있도록 theme resolver를 요청에 바인됭한다.
  • multipart 파일이 확인되면 multipart file resolver는 추가 처리를 위해 MultipartHttpServletRequest로 래핑한다.
  • 요청에 맞는 핸들러가 발견되면 핸틀러와 연결된 전처리기, 후처리기, 컨트롤러를 실행하고, 렌더링할 model을 준비한다. (annotatied controlle인 경우 View 대신 Response를 반환할 수 있다.)
  • Model이 반환되면 View가 렌더링되는데, 반환되지 않으면 이미 요청을 이행했을 거라고 판단하고 View가 렌더링되지 않는다.

렌더링하지 않는 이유는 전처리기와 후처리기에서 가로채기할 수 있는 상황을 방지하기 위해서다.
요청과 응답의 body를 로깅하고 싶다면 body 내부를 읽으면 문제가 발생하니 다른 방법을 강구해야 한다.

profile
익숙함을 경계하자

0개의 댓글