본문 바로가기

Spring

HandlerMapping

Dispatcher Servlet은 프로퍼티로 handlerMapping 구현체 컬렉션을 가지고 있다.

스프링 mvc에서 사용하는 HandlerMapping은 말 그대로 요청을 처리할 핸들러를 연결하는 역할이다. 

HandlerMapping은 아래와 같은 인터페이스이다.

여기서 getHandler를 통해 해당 요청(HttpServletRequest)를 처리할 수 있는 핸들러를 찾아서 HandlerExecutionChain 객체를 반환한다.

HandlerExecutionChain은 간단히 말해, handler와 interceptor등 요청 하나를 처리하기 위한 흐름을 하나의 객체에 모아둔 것이라고 보면 된다. 이를 위해 HandlerMapping의 구현체는 url과 핸들러를 매핑하는 mappingTable을 가지고 있고, 또한 interceptor등의 리스트를 가지고 있다.

 

이러한 HandlerMapping 구현체는 스프링 mvc는 핸들러 타입에 따라 다양하게 존재한다.

몇가지 주요 HandlerMapping을 살펴보자.

 

HandlerMapping 종류

RequestMappingHandlerMapping

: Creates RequestMappingInfo instances from type and method-level @RequestMapping annotations in @Controller classes.

 

이 핸들러 매핑은 스프링 mvc가 제공하는 기본 Handler Mapping이며, @RequestMapping 어노테이션과 @Controller 어노테이션이 붙은 핸들러를 매핑하는 역할이다 (심플한 이름). ReqeustMapping은 spring mvc가 제공하는 어노테이션으로, 독단적으로 사용하는 경우도 있다. 이 어노테이션을 메타 어노테이션으로 사용하는 다른 어노테이션으로는 GetMapping, PostMapping 등이 있다. 즉, GetMapping을 컨트롤러에 붙여도 이는 RequestMappingHandlerMapping에 추가된다.

 

요청의 url을 보고 가장 적합한 RequestMapping를 가진 핸들러를 찾아낸다.

 

BeanNameUrlHandlerMapping

Implementation of the HandlerMapping interface that map from URLs to beans with names that start with a slash ("/"), similar to how Struts maps URLs to action names.

 

등록된 빈 이름 중에 요청의 url과 같은 것을 찾아서 반환한다. 

예를 들어서 /hello 로 요청이 들어왔고 빈의 name이 "/hello"라면 매칭될 수 있다.

 

SimpleUrlMapping

Implementation of the HandlerMapping interface to map from URLs to request handler beans. Supports both mapping to bean instances and mapping to bean names; the latter is required for non-singleton handlers.

 

참고로 resource handler 추가 시 생성되는 핸들러매핑은 SimpleUrlMapping이다.

 

DefaultAnnotationHandlerMapping

RequestMappingHandlerMapping이 나오면서 Deprecated됐고 mvc 5점대 버전에서는 없는 듯 하다.

 

ControllerClassNameHandlerMapping

추후에 적을 예정

 

 

HandlerMapping 우선순위

Dispatcher Servlet은 handlerMappings 프로퍼티(List<HandlerMapping>)를 인덱스 0부터 순회하며 각 HandllerMapping에게 요청을 처리할 수 있는 핸들러를 요구한다. 리스트에 들어있는 순서는 int order라는 프로퍼티로 결정된다. 이 프로퍼티는 HandlerMapping을 상속하는 AbstractHandlerMapping에 존재하고 모든 handler mapping은 이를 상속한다.

 

이 값의 디폴트는 int의 max value로 2147483647이다. 이 값은 낮을 수록 우선순위가 높다. 가장 높은 우선순위는 -2147483648이다. DispatcherServlet.properties를 통해 초기화를 하는 경우, BeanNameUrlHandlerMapping과 RequestMappingHandlerMapping 모두 디폴트 order를 가지도록 설정된다. 선언된 순서대로 리스트에 들어가기 때문에 각각 인덱스는 0, 1 이 된다.

DispatcherServlet.properties

 

@EnableWebMvc를 사용하는 경우 handler mapping에 우선순위를 조금 다르게 설정한다. 이 어노테이션을 통해, 내부적으로 RequestMappingHandlerMapping의 order는 0, BeanNameUrlHandlerMapping의 order는 1 로 세팅한다. 스프링 mvc 프레임워크에서 어노테이션 기반을 조금이라도 더 지원하려고 하는 점이 보이는 것 같다.

 

HandlerExecutionChain

 

 

참고:

https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html

 

 

http://www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte2:ptl:handlermapping#requestmappinghandlermapping_deprecated_defaultannotationhandlermapping%EA%B3%BC_%EA%B1%B0%EC%9D%98_%EB%8F%99%EC%9D%BC

 

egovframework:rte2:ptl:handlermapping [eGovFrame]

DispatcherServlet에 Client로부터 Http Request가 들어 오면 HandlerMapping은 요청처리를 담당할 Controller를 mapping한다. Spring MVC는 interface인 HandlerMapping의 구현 클래스도 가지고 있는데, 용도에 따라 여러 개의 HandlerMapping을 사용하는 것도 가능하다. 빈 정의 파일에 HandlerMapping에 대한 정의가 없다면 Spring MVC는 기본(default)

www.egovframe.go.kr

 

'Spring' 카테고리의 다른 글

ResponseEntity  (0) 2019.06.30
RequestMapping  (0) 2019.06.29
Resource Handler  (0) 2019.06.24
DispatcherServlet  (0) 2019.06.09
ContextLoaderListener  (0) 2019.06.09