10. HandlerMapping → DispatcherServlet: HandlerExecutionChain 반환
HandlerMapping은 단순히 컨트롤러 하나만 찾지 않습니다.
실제 반환값은 핸들러 + 인터셉터 목록이 함께 들어 있는 HandlerExecutionChain이며, DispatcherServlet은 이 실행 단위를 다음 단계에서 그대로 사용합니다.
이번 단계의 역할
요청 처리에 필요한 핸들러와 인터셉터 구성을 한 번에 반환해, DispatcherServlet이 바로 실행 단계로 들어갈 수 있게 만드는 구간입니다.
호출 흐름 요약
HandlerMapping.getHandler(request)가 실행됩니다.- 구현체가 실제 핸들러를 찾습니다.
- 요청에 적용할 인터셉터를 수집합니다.
HandlerExecutionChain을 만들어 DispatcherServlet에 반환합니다.
호출 흐름 다이어그램
sequenceDiagram
participant DispatcherServlet
participant HandlerMapping
participant Chain as HandlerExecutionChain
DispatcherServlet->>HandlerMapping: getHandler(request)
HandlerMapping->>HandlerMapping: 핸들러 매칭
HandlerMapping->>HandlerMapping: 인터셉터 수집
HandlerMapping->>Chain: new(handler, interceptors...)
Chain-->>DispatcherServlet: 반환
핵심 코드
// HandlerExecutionChain.java
public class HandlerExecutionChain {
private final Object handler;
private final List<HandlerInterceptor> interceptorList = new ArrayList<>();
}
// RequestMappingHandlerMapping.java
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
HandlerExecutionChain chain = new HandlerExecutionChain(handler);
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor.matches(request, handler)) {
chain.addInterceptor(interceptor);
}
}
return chain;
}
코드 해설
DispatcherServlet 입장에서는 “핸들러만” 받는 것으로는 부족합니다.
실제로는 그 앞뒤에 어떤 인터셉터가 적용되는지도 알아야 하므로, Spring은 HandlerExecutionChain을 실행 단위로 사용합니다.
설계 의도
1) 핸들러 호출과 인터셉터 실행을 하나의 구조로 묶기 위해
preHandle, postHandle, afterCompletion은 모두 같은 요청 실행 단위에 속해야 합니다.
그래서 Spring은 핸들러와 인터셉터를 분리해서 반환하지 않고 하나로 묶습니다.
2) DispatcherServlet을 단순하게 유지하기 위해
어떤 인터셉터가 붙는지 계산하는 책임은 HandlerMapping에 두고,
DispatcherServlet은 반환된 체인을 실행하는 역할에 집중합니다.
다음 단계 연결
다음 문서 11번에서는 DispatcherServlet이 이 HandlerExecutionChain을 받아 preHandle()을 실제로 실행하는 과정을 봅니다.
← 이전: 9. DispatcherServlet → HandlerMapping | 다음: 11. DispatcherServlet → HandlerInterceptor