DispatcherServlet: Kiến Trúc Front Controller Spring MVC
Khám phá kiến trúc DispatcherServlet trong Spring MVC, 9 bean hạ tầng cốt lõi, vòng đời xử lý request doDispatch và cơ chế auto-config.
TL;DR: DispatcherServlet là Front Controller duy nhất trong Spring MVC tiếp nhận toàn bộ HTTP request trước khi điều phối đến handler phù hợp. Kiến trúc này tập trung các logic dùng chung (xác thực, logging, chuyển đổi định dạng và bắt lỗi) về một điểm duy nhất thay vì lặp lại trên từng servlet riêng lẻ. Servlet ủy thác công việc cho 9 bean hạ tầng cốt lõi như HandlerMapping, HandlerAdapter và HttpMessageConverter. Cơ chế Auto-configuration tự động thiết lập toàn bộ hệ sinh thái này mà không cần cấu hình thủ công.
Vì sao Front Controller giải quyết triệt để hạn chế của Page Controller?
Trong kiến trúc Java EE truyền thống, mô hình Page Controller yêu cầu mỗi đường dẫn URL phải được ánh xạ tới một lớp servlet độc lập:
GET /orders -> OrderListServlet.doGet()
POST /orders -> OrderCreateServlet.doPost()
DELETE /orders/42 -> OrderDeleteServlet.doDelete()
Cách tiếp cận này bộc lộ ba điểm yếu lớn:
- Trùng lặp các mối quan tâm dùng chung (cross-cutting concerns): Mỗi servlet đều phải tự viết lại kiểm tra quyền truy cập, ghi log và xử lý ngoại lệ.
- Cồng kềnh cấu hình: File
web.xmlchứa hàng trăm dòng khai báo ánh xạ servlet phức tạp. - Rất khó viết unit test: Do servlet bị gắn chặt vào servlet container nên khó có thể kiểm thử cô lập logic nghiệp vụ.

Mô hình Front Controller giải quyết triệt để vấn đề trên: một servlet duy nhất (DispatcherServlet) đứng ở cửa ngõ nhận mọi request. Các bộ lọc dùng chung được gắn phía trước, còn các phương thức xử lý nghiệp vụ trở thành những phương thức Java thuần túy (POJO) không còn phụ thuộc trực tiếp vào servlet API.
Bản chất hoạt động của DispatcherServlet và luồng doDispatch là gì?
DispatcherServlet kế thừa trực tiếp từ HttpServlet chuẩn của Java. Khi servlet container tiếp nhận request, phương thức service() sẽ chuyển tiếp đến hàm trung tâm doDispatch(request, response):

Quy trình 9 bước điều phối chuẩn xác:
- Servlet container (như Tomcat) nhận request và chuyển vào
DispatcherServlet.doDispatch(). - Hàm
getHandler(request)duyệt qua danh sáchHandlerMappingđể tìm kiếm controller method phù hợp. - Trả về
HandlerExecutionChainchứa method đích cùng danh sách các interceptor liên quan. getHandlerAdapter(handler)tìm kiếm adapter tương thích với loại controller được gọi.- Thực thi phương thức
preHandle()trên từng interceptor; nếu trả vềfalse, chuỗi xử lý dừng lại ngay lập tức. - Adapter giải nén tham số từ HTTP request và gọi thực thi method của controller.
- Controller xử lý logic và trả về dữ liệu kết quả (dạng object hoặc
ResponseEntity). HttpMessageConverterchuyển đổi đối tượng trả về thành chuỗi JSON/XML trong thân HTTP response.- Thực thi lần lượt
postHandle()vàafterCompletion()trên các interceptor theo chiều ngược lại.
9 bean hạ tầng nào cùng phối hợp trong DispatcherServlet?
Để đảm bảo nguyên lý Dependency Inversion, DispatcherServlet không tự xử lý toàn bộ công việc mà ủy nhiệm cho 9 bean hạ tầng:
| Thành phần Bean | Chức năng chính | Triển khai mặc định trong Boot |
|---|---|---|
HandlerMapping | Ánh xạ URL và HTTP method tới controller method | RequestMappingHandlerMapping |
HandlerAdapter | Điều phối gọi controller và giải nén tham số | RequestMappingHandlerAdapter |
HandlerInterceptor | Can thiệp trước và sau khi controller thực thi | Đăng ký qua WebMvcConfigurer |
HttpMessageConverter | Chuyển đổi thân HTTP body qua lại với Java object | MappingJackson2HttpMessageConverter |
HandlerExceptionResolver | Bắt và chuyển đổi Exception thành HTTP response | ExceptionHandlerExceptionResolver |
ViewResolver | Phân giải tên view cho ứng dụng MVC truyền thống | ContentNegotiatingViewResolver |
LocaleResolver | Xác định ngôn ngữ vùng miền từ request header | AcceptHeaderLocaleResolver |
MultipartResolver | Phân tích dữ liệu upload file đa phần | StandardServletMultipartResolver |
ThemeResolver | Phân giải giao diện người dùng (hiện đã deprecated) | FixedThemeResolver |
Khi một ngoại lệ xuất hiện trong controller, hệ thống chuyển giao cho chuỗi HandlerExceptionResolver để định dạng mã lỗi:

Spring Boot tự động cấu hình DispatcherServlet như thế nào?
Spring Boot tự động thiết lập toàn bộ hệ thống thông qua hai lớp auto-configuration:
DispatcherServletAutoConfiguration chịu trách nhiệm khởi tạo bean DispatcherServlet và đăng ký với Tomcat dưới đường dẫn "/":
@AutoConfiguration
@ConditionalOnWebApplication(type = SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
public class DispatcherServletAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
}
Kế đến, WebMvcAutoConfiguration nạp toàn bộ 9 bean hạ tầng đi kèm:
@AutoConfiguration(after = DispatcherServletAutoConfiguration.class)
@ConditionalOnWebApplication(type = SERVLET)
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
public class WebMvcAutoConfiguration {
// Registers RequestMappingHandlerMapping, Jackson converters, etc.
}
Để thêm interceptor hoặc cấu hình CORS mà không làm mất các thiết lập mặc định, lập trình viên sử dụng giao diện WebMvcConfigurer:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("https://olhub.vn");
}
}
Điểm khác biệt mấu chốt giữa Servlet Filter và HandlerInterceptor là gì?
Cả hai đều có khả năng chặn bắt request nhưng hoạt động ở hai tầng kiến trúc hoàn toàn tách biệt:

| Tiêu chí so sánh | Servlet Filter | HandlerInterceptor |
|---|---|---|
| Tầng kiến trúc | Servlet API (nằm ngoài DispatcherServlet) | Spring MVC (nằm trong DispatcherServlet) |
| Thời điểm thực thi | Chạy cho mọi request trước khi vào servlet | Chỉ chạy sau khi URL đã khớp với controller |
| Nhận diện Controller | Không biết method nào sẽ xử lý | Nhận đối tượng HandlerMethod cụ thể |
| Ngữ cảnh phù hợp | Xác thực Token, CORS, nén dữ liệu | Đo lường thời gian controller, audit log |
Những lỗi cấu hình kinh điển nào thường gặp với DispatcherServlet?
Dưới đây là các cạm bẫy cấu hình cần tránh:
- Thêm annotation
@EnableWebMvctrong Spring Boot: Làm vô hiệu hóa hoàn toànWebMvcAutoConfiguration, khiến ứng dụng mất bộ chuyển đổi Jackson JSON và trang lỗi mặc định. - Dùng interceptor để xác thực bảo mật thay vì Filter: Khi client gửi request đến một đường dẫn 404 không tồn tại, interceptor sẽ không chạy, làm hở các lỗ hổng giám sát.
- Ghi đè nhầm
configureMessageConverters: Phương thức này sẽ xóa sạch các converter mặc định của Spring Boot. Luôn dùngextendMessageConvertersnếu chỉ muốn bổ sung converter mới.
Tóm tắt
DispatcherServlethiện thực mẫu Front Controller, đóng vai trò cửa ngõ tập trung toàn bộ HTTP request.- Phương thức
doDispatch()điều phối quy trình 9 bước từ tìm kiếm handler đến tuần tự hóa dữ liệu phản hồi. - 9 bean hạ tầng đảm nhiệm các tác vụ độc lập, giúp hệ thống dễ dàng mở rộng theo nguyên lý hướng đối tượng.
- Mở rộng cấu hình tầng web an toàn bằng cách implement
WebMvcConfigurervà tránh lạm dụng@EnableWebMvc. - Servlet Filter hoạt động ở tầng ngoài cùng của servlet container, trong khi
HandlerInterceptorcan thiệp sâu vào ngữ cảnh controller của Spring.
Tự kiểm tra
- Q1Front Controller pattern trong Spring MVC giải quyết vấn đề cốt lõi nào của mô hình Page Controller cũ?
- Q2Điều gì sẽ xảy ra nếu lập trình viên khai báo thêm annotation @EnableWebMvc trong dự án Spring Boot thông thường?
- Q3Một request gửi tới URL không tồn tại (trả về lỗi 404). HandlerInterceptor đã đăng ký có được kích hoạt phương thức preHandle() không?
- Q4Thành phần bean hạ tầng nào chịu trách nhiệm chuyển đổi thân HTTP Request (JSON) thành Java Object trước khi gọi method controller?
- Q5Để đo thời gian thực thi của một controller method cụ thể kèm tên class và tên method, thành phần nào là lựa chọn tối ưu nhất?
Bài tiếp theo: URL Routing & Request Pipeline
Bài này có giúp bạn hiểu bản chất không?
Bài này đáng gửi cho bạn học cùng?
Copy link đã gắn nguồn — dán group, chat, hoặc LinkedIn.
Tổng Quan Module 01: Kiến Trúc Spring MVC Core
Bài tiếpURL Routing Pipeline: HandlerMapping Và PathPattern
Lộ trình Junior Java Backend Developer
Chặng 15/21 · REST API với Spring MVC — bài 2/21 của chặng
Thảo luận & góp ý
Hỏi đáp về bài này