Spring MVC를 공부하면 가장 먼저 나오는 단어가 DispatcherServlet이다. "DispatcherServlet가 모든 요청을 받아서 적절한 Controller에 전달한다"라는 설명은 어디서든 볼 수 있다.
DispatcherServlet을 이해하려면 먼저 Servlet이 뭔지 알아야 한다. 그래야 "왜 DispatcherServlet이 필요한지"가 자연스럽게 이해된다.
Servlet이란?
Servlet은 클라이언트의 HTTP 요청을 받아서 처리하고, HTTP 응답을 만들어 돌려주는 자바 객체다.
웹 브라우저가 http://localhost:8080/hello에 접속하면, 서버 어딘가에서 이 요청을 받아서 "Hello"라는 응답을 만들어줘야 한다. 그 "어딘가"가 바로 Servlet이다.
doGet()이 GET 요청을 처리하고, doPost()가 POST 요청을 처리한다.
// 가장 기본적인 Servlet
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.setContentType("text/html");
response.getWriter().write("<h1>Hello!</h1>");
}
}
Servlet은 혼자 동작하지 않는다
Servlet 자체는 그냥 자바 클래스다. 이걸 실행하려면 서블릿 컨테이너가 필요하다. 대표적으로 Tomcat이 있다.
서블릿 컨테이너가 하는 일
- 네트워크 통신 (소켓, HTTP 파싱)
- Servlet 객체의 생명주기 관리 (생성, 초기화, 소멸)
- 요청 URL과 Servlet 매핑
- 멀티스레드 처리
URL과 Servlet을 연결하는 방법
옛날에는 web.xml에 일일이 매핑했다.
<!-- web.xml -->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.example.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
/hello로 요청이 오면 HelloServlet이 처리한다. 직관적이지만 문제가 있다.
Servlet만으로 웹 애플리케이션을 만들면? → URL이 10개면 Servlet도 10개, 매핑도 10개다.
/hello → HelloServlet
/user → UserServlet
/order → OrderServlet
/product → ProductServlet
/login → LoginServlet
...
1. 공통 로직이 중복된다
인증 체크, 로깅, 예외 처리, 인코딩 설정 같은 건 모든 Servlet에서 필요하다. 그런데 Servlet마다 각각 작성해야 한다.
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
// 인증 체크 (중복)
if (!isAuthenticated(request)) { ... }
// 인코딩 설정 (중복)
response.setCharacterEncoding("UTF-8");
// 실제 로직
...
}
}
public class OrderServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
// 인증 체크 (또 중복)
if (!isAuthenticated(request)) { ... }
// 인코딩 설정 (또 중복)
response.setCharacterEncoding("UTF-8");
// 실제 로직
...
}
}
2. Spring IoC 컨테이너와 연결이 안 된다
Servlet은 서블릿 컨테이너(Tomcat)가 관리하는 객체다. Spring이 관리하는 Bean이 아니다. 그래서 @Autowired로 의존성 주입을 받을 수 없다.
3. URL이 늘어날수록 관리가 힘들다
web.xml에 매핑이 수십 개 쌓이면 어떤 URL이 어떤 Servlet인지 추적하기 어려워진다.
이 문제들을 한 번에 해결하는 게 Front Controller 패턴이다.
Front Controller 패턴
아이디어는 단순하다. Servlet을 하나만 두고, 이 하나가 모든 요청을 받아서 적절한 곳으로 분배하면 된다.

공통 로직(인증, 로깅, 예외처리)은 FrontController 한 곳에서 처리하면 중복이 사라진다.
Spring MVC에서 이 FrontController 역할을 하는 게 바로 DispatcherServlet이다.
DispatcherServlet이란?
DispatcherServlet은 Spring MVC의 핵심이자 모든 HTTP 요청의 단일 진입점이다. 이름 그대로 요청을 받아서 적절한 곳으로 디스패치(배차)해주는 서블릿이다. DispatcherServlet 공식문서🔗
DispatcherServlet도 결국 HttpServlet을 상속한 Servlet이다. Tomcat 같은 서블릿 컨테이너 위에서 동작한다.
HttpServlet ← Java EE 표준
└─ HttpServletBean ← init-param → 빈 프로퍼티 매핑
└─ FrameworkServlet ← WebApplicationContext 초기화
└─ DispatcherServlet ← 실제 요청 라우팅 (doDispatch())
Spring이 추가함..
- FrameworkServlet : Spring의 WebApplicationContext를 초기화하고 연결
- DispatcherServlet : doDispatch() 메서드에서 요청을 적절한 Controller로 라우팅
[ DispatcherServlet이 해주는 일 ]
| 역할 | 설명 |
| HandlerMapping | URL → 어떤 Controller가 처리할지 찾기 |
| HandlerAdapter | 다양한 타입의 핸들러를 통일된 방식으로 실행 |
| ViewResolver | 뷰 이름 → 실제 뷰 파일로 변환 |
| ExceptionResolver | 예외 처리 통합 |
| Interceptor | 공통 로직(인증, 로깅) 한 곳에서 처리 |
Servlet 여러 개로 할 때의 문제가 전부 해결된다.
- 공통 로직? → Interceptor로 한 곳에서 처리
- Spring IoC? → DispatcherServlet이 WebApplicationContext를 들고 있어서 Bean 관리 가능
- URL 관리? → @GetMapping("/hello") 어노테이션으로 코드에서 바로 매핑
DispatcherServlet의 요청 처리 흐름의 핵심은 DispatcherServlet이 중앙에서 다른 컴포넌트에 위임하는 구조라는 것이다. 각 컴포넌트(HandlerMapping, HandlerAdapter, ViewResolver 등)의 상세한 동작은 다음 글에서 다룬다.
정리
Servlet은 HTTP 요청을 처리하는 자바 객체이고, DispatcherServlet은 그 Servlet을 확장해서 모든 요청을 하나로 받아 적절한 Controller에 배차해주는 Spring MVC의 핵심이다.
| Servlet | DispatcherServlet | |
| 개념 | HTTP 요청을 처리하는 자바 객체 | Servlet을 확장한 Spring MVC의 Front Controller |
| 개수 | URL마다 하나씩 | 하나로 모든 요청 처리 |
| 공통 로직 | 각 Servlet에서 중복 작성 | Interceptor로 한 곳에서 처리 |
| Spring 연동 | 직접 불가 (Tomcat이 관리) | WebApplicationContext로 완전 통합 |
| URL 관리 | web.xml에 매핑 | @GetMapping 등 어노테이션으로 관리 |
관련 포스팅
다음 글: [Spring] Spring MVC 요청 처리 흐름 정리
'Spring' 카테고리의 다른 글
| [Spring] Spring MVC 요청 처리 흐름 정리 (0) | 2026.03.31 |
|---|---|
| [Spring] Bean이란? (0) | 2026.01.24 |
| [Spring] DI(Dependency Injection) (0) | 2026.01.12 |
| [Spring] IoC(Inversion of Control) (0) | 2025.12.31 |
| [Spring] 스프링의 3계층 구조 : Controller, Service, Repository (1) | 2025.12.11 |