리루

Dispatcher Servlet의 동작원리 본문

#Spring

Dispatcher Servlet의 동작원리

뚱보리루 2020. 2. 2. 13:38

- 용어

 - HandlerMapper : Handler를 찾아주는 인터페이스

 - HandlerAdaptor : Handler를 수행해주는 인터페이스

 - View Resolver : View 이름(String 값)을 갖고 실제 매핑되는 View 파일(리소스)을 찾아 변환하는 인터페이스.

 

- 구성

 1.  MultipartResolver interface

 : 파일 업로드 요청 처리에 필요한 인터페이스(http 요청에서 content-type : multipart 은 경우, 바이너리로 쪼개져서 날아오는 파일들을 받기위한 처리 작업을 한 것으로 예상, HttpServletRequest -> MultipartHttpServletRequest로 변환)

 : DispatcherServlet에는 DefaultStratage로 등록된 Bean은 없고, SpringBoot에서는 StandardServletMultipartResolver가 기본으로 등록된다.

 

2. LocaleResolver

 : Client 위치 정보, 지역정보를 확인하는데 사용됨. --> 지역에 따라 적절한 지역언어의 메시지로 화면을 전달하기 위함

 : DispatcherServlet 기준으로 기본등록되는 구현체는 AcceptHeaderLocaleResolver이다(요청에 들어있는 accept-language header 값으로 파악).

 : MultipartResolver, LocaleResolver는 요청이 Dispatcher servlet에 들어왔을때, 요청을 분석하는데 사용됨.

 

3. ThemeResolver

 : 애플리케이션에서 설정 테마를 파악하고 변경할 수 있는 인터페이스

 : Theme이라는 키값을 view에 전달하고, view에서 key 값에 맞는 css 등을 불러와서 적용시키는 기능.

 

4. HandlerMapping

 : 어떤 요청이 들어왔을 때, 그 요청을 처리할 Handler를 찾는 인터페이스.

 : 기본 구현체 1) RequestMappingHandlerMapping은 애노테이션 기반으로 핸들러를 찾아준다. 이 경우에는 method 자체가 핸들러가 된다.(* @Controller 같은 애노테이션을 이용해 핸들러를 만들 수 있는 이유는 기본적으로 해당 HandlerMapping이 등록되어 있기 때문이다.)

 : 기본 구현체 2) BeanNameUrlHandlerMapping은 빈 이름 기반으로 이 요청에 해당하는 Bean이 있는가를 찾는다. 이 경우에는 Class가 핸들러가 된다.

 

5. HandlerAdaptor

 : HandlerMaaping이 찾아낸 (마음대로, 제멋대로 생긴) 핸들러를 처리하는 인터페이스

 : Spring MVC 확장력의 핵심 : 핸들러를 원하는대로 커스텀 해서 만들 수 있다.

 : 기본 구현체 1) RequestMappingHandlerAdaptor 가 등록됨(RequestMappingHandlerMapping 와 세트를 이루면 작동)

 : 2) HttpRequestHandlerAdaptor, 3) SimpleControllerHandlerAdaptor

 

6. HandlerExceptionResolver

 : DispatcherServlet 실행 중에 전반적으로 일어나는 예외들에 대해서 해당 예외에 따라 맞는 예외처리를 해준다. 

 : 기본으로 ExceptionHandlerExceptionResolver를 주로 사용할 것 : @ExceptionHandler 애노테이션에 따른 동작을 한다.

 

* HandlerMapping, HandlerAdaptor, HandlerExceptionResolver 는 Collection으로 복수개의 구현체를 갖고 있으며 이를 순회하며 작동한다. 또한 @Order 를 사용한 순회 순서도 정해질 수 있다. 

 

7. RequestToViewNameTranslator

 : 핸들러에서 뷰 이름을 명시적으로 리턴하지 않는 경우(핸들러 매서드 반환타입이 void인 경우 등), 요청 기반으로 뷰 이름을 판단하는 인터페이스

 : 기본 구현체는 DefualtRequestToViewNameTranslator 하나이고, url과 동일하게 view 네임으로 사용하는 것으로 예상.

 

8. ViewResolver

 : 명시적으로 view 이름을 가져오든, RequestToViewNameTranslator를 통해서 view 이름을 추측하든 View 이름을 가져온 후, 이름을 갖고 실제 View를 찾아내는 인터페이스.

 : DispatcherServlet 기준으로 기본적으로 InternalResourceViewResolver가 등록되어있다.

 : SpringBoot에는 더 많은 구현체가 기본적으로 등록되어 있다.

 

9. FlashMapResolver

 : 어떤 데이터를 받고, 저장한 후 그 다음에 보통 리다이렉트를 하는데,

 : 왜? 화면에서 refresh 했을 때 같은 요청을 반복하면 동일한 데이터가 반복해서 넘어온다. 이를 방지하기 위한 패턴

 : 사실 뭔지 잘 모르겠다. 중복 from submission을 방지하기 위한 패턴.

 

- 응용

 - Spring MVC가 기본적으로 갖고있는 Handler Mapping에는 1. BeanNameUrlHandlerMapping(요청한 url과 빈의 이름이 일치하는 빈을 찾아준다.), 2. RequestMappingHandlerMapping(@RequestMapping이라는 애노테이션을 컨트롤러 클래스나 메서드에 선언하여 사용)가 있다.

 

 - View Resolver 동작 원리 

 : org.springframework.web.servlet.DispatcherServlet Class 에 servlet을 초기화하는 protected void initStrategies(ApplicationContext context) 내 initViewResolver(context); 수행.(이는 매 요청마다 수행되는 것이 아니라 최초 dispatcher servlet을 초기화 하기위해 한번만 호출된다.)

 : 등록된 Bean에서 ViewResolver.class 타입의 Bean을 모두 찾아와서 veiwResolvers List에 넣어둔다.

 : 만약 개발자가 등록한 ViewResolver.class 타입의 Bean이 없다면, getDefaultStrategies(context, ViewResolver.class) 수행을 통해서 기본 전략을 가져온다. 이 기본 전략에 internalResourceViewResolver가 들어있다.

 : 이는 DispatcherServlet.properties 라는 파일에서 기본전략으로 가져올 내용들을 관리한다. HandlerMapper의 경우에도 이와 마찬가지로 해당 파일에 BeanNameUrlHandlerMapping과 RequestMappingHandlerMapping 값을 갖고 있다.

 

 

 - DispatcherServlet.properties

# Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver

org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,\
	org.springframework.web.servlet.function.support.RouterFunctionMapping

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\
	org.springframework.web.servlet.function.support.HandlerFunctionAdapter


org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
	org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
	org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

 

[참고] Infrean 백기선의 스프링 웹 MVC, (매우 유용하고 친절한 강의라고 생각합니다. 들으시면 기본적인 구조나 원래를 익히는데 도움이 되실 것 같습니다!! 20% 할인하는 기간도 간간히 있으니 잘 활용하세용~)

'#Spring' 카테고리의 다른 글

2. Servlet (써블릿) - 원시적인 코드로 확인  (0) 2020.02.02
1. Servlet (써블릿) - 기본 설명  (0) 2020.02.02
JPA Study  (0) 2019.05.19
Spring IoC / Bean  (0) 2019.03.25
Annotation을 이용한 Spring 설정  (0) 2019.01.06