Spring Framework 시리즈 12화 – Spring MVC 구조의 출발점: DispatcherServlet과 요청 처리 흐름
Spring MVC에서 요청이 들어오면 어떤 경로를 따라 응답이 만들어질까요? DispatcherServlet을 중심으로, HandlerMapping, Controller, ViewResolver까지의 흐름을 자연스럽게 정리합니다.
Spring MVC의 진짜 시작점은?
우리는 보통 컨트롤러부터 코드를 쓰기 시작합니다.
@GetMapping("/hello")
public String hello() {
return "hello";
}
근데 정말 이게 전부일까요?
이렇게 작성된 코드는 어떻게 실행되고, 어떻게 우리가 작성한 뷰 이름을 찾아가는 걸까요?
그 중심에는 바로 DispatcherServlet이 있습니다.
사실상 Spring MVC의 모든 요청은 DispatcherServlet을 거쳐서 흐릅니다.
DispatcherServlet? 그냥 톰캣에서 실행되는 서블릿?
맞습니다. DispatcherServlet은 javax.servlet.http.HttpServlet을 상속한 스프링 전용 서블릿입니다.
하지만 이 서블릿은 단순한 컨트롤러 실행기가 아닙니다.
스프링 내부에서 요청을 받아, 다음과 같은 일을 순서대로 해주는 중앙 처리기입니다.
요청 흐름 한눈에 보기
클라이언트 요청 → DispatcherServlet →
1. HandlerMapping → 어떤 컨트롤러?
2. HandlerAdapter → 컨트롤러 실행
3. Controller → 결과(Model, View 이름) 반환
4. ViewResolver → 뷰 템플릿 경로 찾기
5. ViewRenderer → 화면 렌더링
DispatcherServlet은 이 모든 역할을 오케스트라처럼 지휘합니다.
그럼 실제로는 어떤 클래스들이 작동할까?
1. HandlerMapping
요청 URL이 들어왔을 때 어떤 컨트롤러가 처리할지 결정합니다.
Spring Boot에서는 내부적으로 RequestMappingHandlerMapping이 이 역할을 합니다.
2. HandlerAdapter
컨트롤러를 실행하는데 필요한 조건을 체크하고, 어떻게 실행할지를 결정합니다.
- @RestController인지
- ModelAndView를 반환하는지 등
3. Controller
우리가 직접 작성하는 부분이죠. 예:
@Controller
public class HelloController {
@GetMapping("/hello")
public String hello(Model model) {
model.addAttribute("message", "안녕하세요!");
return "hello"; // hello.html을 의미
}
}
4. ViewResolver
"hello"라는 문자열을 어떤 HTML 파일로 매핑할지 결정합니다.
Spring Boot의 기본 설정이라면 다음과 같이 작동합니다:
"hello" → /templates/hello.html (Thymeleaf 기준)
5. ViewRenderer
이제 실제 뷰 템플릿(HTML)을 렌더링해서 브라우저로 전송합니다.
흐름을 전체적으로 정리하면 이런 느낌입니다
[요청] /hello
↓
DispatcherServlet
↓
HandlerMapping → HelloController 매핑됨
↓
HandlerAdapter → hello() 실행
↓
Model + "hello" 뷰 이름 반환
↓
ViewResolver → hello.html
↓
ViewRenderer → HTML 렌더링
↓
[응답] 200 OK
실전에서 DispatcherServlet이 진짜 하는 일?
- 모든 요청을 위임받음
- Spring MVC 내부 컴포넌트를 호출
- 예외가 발생하면 ExceptionResolver를 통해 처리
- 마지막까지 뷰 렌더링까지 책임지고 마무리
DispatcherServlet이 자동 등록되는 이유
Spring Boot에서는 @SpringBootApplication이 실행되면 내부적으로 다음과 같은 설정이 적용됩니다:
@Bean
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
그리고 이 서블릿은 / 경로에 자동으로 매핑됩니다.
그래서 우리가 별도로 web.xml을 쓰지 않아도 작동하는 것이죠.
정리: DispatcherServlet은 Spring MVC의 프런트 컨트롤러
- 요청을 받고
- 어떤 컨트롤러가 처리할지 결정하고
- 결과를 받고
- 뷰로 보내고
- 응답을 전송하는
스프링 MVC의 심장 같은 존재입니다.
우리가 보통 신경 쓰지 않는 이 구조를 이해하면, 디버깅이 쉬워지고 스프링이 왜 이렇게 동작하는지를 설명할 수 있게 됩니다.
다음 편 예고
13화에서는 실제로 @Controller, @RestController, @RequestMapping이 어떤 구조로 DispatcherServlet과 연동되는지, 그리고 어떤 애노테이션이 어떤 HandlerMapping과 연결되는지를 집중적으로 다뤄봅니다.