DispatcherServlet은 Spring MVC의 핵심 컴포넌트로, 프론트 컨트롤러(Front Controller) 패턴을 구현한 클래스이다. 서블릿 필터를 거친 후의 모든 HTTP 요청을 받아 적절한 컨트롤러로 위임하는 역할을 한다.
// DispatcherServlet 내부 로직 (의사 코드)
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) {
// 1. 핸들러 찾기
HandlerExecutionChain mappedHandler = getHandler(request);
// 2. 핸들러 어댑터 찾기
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 3. 핸들러 실행
ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler());
// 4. 뷰 처리
processDispatchResult(request, response, mappedHandler, mv);
}
요청 접수
클라이언트로부터 HTTP 요청이 들어오면 DispatcherServlet이 가장 먼저 요청을 받습니다.
web.xml 또는 Java Config를 통해 URL 패턴을 지정할 수 있으며, 보통 "/"로 설정하여 모든 요청을 처리한다.
핸들러(컨트롤러) 매핑
HandlerMapping을 통해 요청 URL에 매핑된 핸들러(컨트롤러)를 조회한다.
RequestMappingHandlerMapping이 가장 많이 사용되며, @RequestMapping 어노테이션을 통해 매핑된다.
핸들러 어댑터 조회
해당 핸들러를 실행할 수 있는 HandlerAdapter를 조회한다.
RequestMappingHandlerAdapter가 주로 사용되며, @RequestMapping 기반의 컨트롤러를 처리한다.
핸들러 실행
HandlerAdapter를 통해 핸들러를 실행한다.
컨트롤러의 비즈니스 로직이 실행되고 ModelAndView를 반환한다.
뷰 리졸버
ViewResolver를 통해 뷰의 논리 이름을 실제 뷰 객체로 변환한다.
예를 들어, "home"이라는 논리 이름을 "/WEB-INF/views/home.jsp"와 같은 실제 뷰 경로로 변환한다.
뷰 렌더링
View 객체를 통해 실제 뷰를 렌더링한다.
JSP, Thymeleaf 등 다양한 템플릿 엔진을 지원한다.
DispatcherServlet은 HandlerExceptionResolver를 통해 예외를 처리한다.
@ExceptionHandler, @ControllerAdvice 등을 통해 전역 예외 처리가 가능하다.
HandlerInterceptor를 구현하여 컨트롤러 실행 전후에 공통 로직을 수행할 수 있다.
로깅, 인증, 권한 체크 등에 활용된다.
MultipartResolver를 통해 파일 업로드와 같은 멀티파트 요청을 처리한다.
CommonsMultipartResolver 또는 StandardServletMultipartResolver를 주로 사용한다.
중앙 집중식 요청 처리
유연한 설계
확장성
@ExceptionHandler와 @ControllerAdvice는 DispatcherServlet의 예외 처리 메커니즘의 일부이다.
try {
// DispatcherServlet이 요청을 처리하는 과정
doDispatch(request, response);
} catch (Exception ex) {
// 예외가 발생하면 예외 처리 메커니즘으로 전달
processHandlerException(request, response, handler, ex);
}
DispatcherServlet은 기본적으로 여러 HandlerExceptionResolver를 가지고 있다.
컨트롤러 내부의 @ExceptionHandler (가장 높음)
@ControllerAdvice 클래스의 @ExceptionHandler
ResponseStatusExceptionResolver
DefaultHandlerExceptionResolver (가장 낮음)
@ExceptionHandler 메서드 검색
예외 타입 매칭
적절한 응답 생성 (JSON, XML, 뷰 등)
중앙 집중식 예외 처리가 가능
일관된 예외 처리 방식 제공
예외 처리의 재사용성 향상
DispatcherServlet이 예외 처리의 진입점 역할을 하고, 실제 처리는 각각의 HandlerExceptionResolver가 담당한다.
Spring Interceptor는 핸들러 매핑 이후, 핸들러 실행 전후에 실행된다.
@Component
public class LoggingInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
// 컨트롤러 실행 전 처리
log.info("preHandle: " + request.getRequestURI());
return true; // false를 반환하면 요청 중단
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
// 컨트롤러 실행 후, 뷰 렌더링 전 처리
log.info("postHandle: " + request.getRequestURI());
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
// 뷰 렌더링 후 처리
log.info("afterCompletion: " + request.getRequestURI());
}
}
HTTP Request
→ WAS(톰캣)
→ Filter1
→ Filter2
→ DispatcherServlet
→ Interceptor1
→ Interceptor2
→ Controller
← Interceptor2
← Interceptor1
← DispatcherServlet
← Filter2
← Filter1
← WAS(톰캣)
← HTTP Response
@Component
public class CustomFilter implements Filter {
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// DispatcherServlet 실행 전 처리
chain.doFilter(request, response);
// DispatcherServlet 실행 후 처리
}
}
실행 시점
스프링 관리 여부
사용 용도