What Is DispatcherServlet in Spring? The Core Component Every Boot Developer Needs to Understand
Problem
When I work with Spring Boot developers, I often see a pattern: they can create @Controller classes, add @GetMapping methods, and requests magically route correctly. Everything “just works.” But when something breaks—a 404 that shouldn’t exist, a filter not executing, or a custom configuration not applying—they have no idea what’s happening under the hood.
The core issue: Spring Boot developers often skip learning DispatcherServlet because the framework abstracts it away completely.
One developer on Reddit put it well: “If you start with Boot, just make sure to eventually learn the Spring MVC core concepts (like the DispatcherServlet, the Request Lifecycle, and Annotations), because when something breaks or performance drops, you’ll need to know how the underlying ‘engine’ actually works to fix it.”
I think of Spring Boot as Spring MVC with “auto-pilot” turned on. DispatcherServlet is part of understanding that underlying engine.
What DispatcherServlet Actually Is
DispatcherServlet is Spring MVC’s implementation of the Front Controller pattern—a single servlet that receives all HTTP requests and coordinates the entire request processing pipeline.
Think of it as the traffic controller at a busy intersection. Every request passes through it, and it directs each one to its destination.
+--------------------------------------------------+| DispatcherServlet || (The Front Controller) |+--------------------------------------------------+ | | | v v v +-----------+ +-----------+ +-----------+ |ControllerA| |ControllerB| |ControllerC| +-----------+ +-----------+ +-----------+ | | | v v v /users /products /ordersWithout DispatcherServlet, you’d need a separate servlet for each URL pattern. With it, you have one central point that:
- Receives every HTTP request
- Routes requests to the correct controller method
- Handles view rendering
- Manages the complete request-response lifecycle
How DispatcherServlet Processes Requests
When a request hits your Spring Boot application, here’s what happens:
HTTP Request (GET /users/123) | v+------------------------+| DispatcherServlet | <-- 1. Receives all requests+------------------------+ | v+------------------------+| HandlerMapping | <-- 2. Finds which controller method+------------------------+ should handle this URL | v+------------------------+| HandlerAdapter | <-- 3. Invokes the controller method+------------------------+ | v+------------------------+| Controller Method | <-- 4. Your @GetMapping method executes+------------------------+ | v+------------------------+| ModelAndView | <-- 5. Returns data + view name| or @ResponseBody | (or just data for REST APIs)+------------------------+ | v+------------------------+| ViewResolver | <-- 6. Finds the actual view template+------------------------+ (if returning a view) | v+------------------------+| View | <-- 7. Renders the response+------------------------+ | vHTTP Response (JSON or HTML)Let me show you what this looks like in code. Here’s a simple controller:
@RestController@RequestMapping("/api/users")public class UserController {
private final UserService userService;
public UserController(UserService userService) { this.userService = userService; }
@GetMapping("/{id}") public ResponseEntity<User> getUser(@PathVariable Long id) { return userService.findById(id) .map(ResponseEntity::ok) .orElse(ResponseEntity.notFound().build()); }}When a request comes to GET /api/users/123, DispatcherServlet:
- Receives the request
- Asks HandlerMapping: “Which method handles
/api/users/{id}?” - HandlerMapping returns the
getUsermethod onUserController - HandlerAdapter invokes that method with
id = 123 - The method returns a
ResponseEntity - Since it’s
@RestController, the response body is serialized to JSON
Why Boot Developers Need to Understand This
You might wonder: “If Spring Boot configures everything automatically, why do I need to know this?”
Here are scenarios where understanding DispatcherServlet is critical:
Debugging 404 Errors
Your controller looks correct, but requests return 404. Without understanding the HandlerMapping step, you’re guessing. The issue could be:
- URL pattern mismatch
- Component scanning not picking up your controller
- Multiple HandlerMappings conflicting
Understanding Filter vs Interceptor Order
Request | v+------------------+ Filters execute here| Filter A | (Servlet level)+------------------+ | v+------------------+| Filter B |+------------------+ | v+------------------------+| DispatcherServlet | <-- Interceptors execute here+------------------------+ (Spring MVC level) | v+------------------+| Interceptor 1 |+------------------+ | v+------------------+| Interceptor 2 |+------------------+ | v ControllerFilters run before DispatcherServlet; Interceptors run after. This matters when you need to intercept requests at the right level.
Customizing Error Handling
When you create a @ControllerAdvice with @ExceptionHandler, it only catches exceptions from controllers. Exceptions thrown in filters won’t be caught. Why? Because filters execute before DispatcherServlet, so your controller advice never sees them.
Adding Custom Argument Resolvers
If you need to inject custom objects into controller methods:
public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver {
@Override public boolean supportsParameter(MethodParameter parameter) { return parameter.getParameterType().equals(User.class) && parameter.hasParameterAnnotation(CurrentUser.class); }
@Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { // Extract user from request/session return webRequest.getAttribute("user", RequestAttributes.SCOPE_REQUEST); }}You register this with DispatcherServlet:
@Configurationpublic class WebConfig implements WebMvcConfigurer {
@Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { resolvers.add(new CurrentUserArgumentResolver()); }}Multipart File Uploads
When configuring file upload limits, you’re configuring DispatcherServlet:
spring.servlet.multipart.max-file-size=10MBspring.servlet.multipart.max-request-size=10MBThese properties configure the MultipartResolver that DispatcherServlet uses.
Common Mistakes I See
| Mistake | Why It’s Wrong | What to Do Instead |
|---|---|---|
| Thinking controllers receive requests directly | DispatcherServlet invokes them | Understand the front controller pattern |
| Not knowing why filters run before interceptors | Different levels in the stack | Filters are servlet-level, interceptors are MVC-level |
| Assuming Boot’s auto-configuration covers all scenarios | Sometimes you need to customize | Learn when and how to override defaults |
| Ignoring request lifecycle when debugging | Everything flows through DispatcherServlet | Trace requests through the pipeline |
Not understanding @ControllerAdvice scope | Only catches controller exceptions | Know what exceptions it can and can’t catch |
A Mental Model That Helps Me
I think of the Spring request handling like a company:
+------------------------+| Client (Browser) | <-- Customer+------------------------+ | v+------------------------+| DispatcherServlet | <-- Receptionist (routes all requests)+------------------------+ | v+------------------------+| HandlerMapping | <-- Directory (finds the right department)+------------------------+ | v+------------------------+| Controller | <-- Department (handles specific requests)+------------------------+ | v+------------------------+| Service | <-- Specialist (does the actual work)+------------------------+ | v+------------------------+| Repository | <-- Archive (stores/retrieves data)+------------------------+The receptionist (DispatcherServlet) doesn’t do the work—they route requests to the right department. Each department (Controller) has specialists (Services) who do the actual work.
What Happens Without DispatcherServlet
In traditional Java web development without Spring MVC, you’d have something like this:
@WebServlet("/users/*")public class UserServlet extends HttpServlet {
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String pathInfo = req.getPathInfo(); if (pathInfo == null || pathInfo.equals("/")) { // Handle list users List<User> users = userService.findAll(); resp.setContentType("application/json"); resp.getWriter().write(objectMapper.writeValueAsString(users)); } else { // Handle get single user Long id = Long.parseLong(pathInfo.substring(1)); User user = userService.findById(id); if (user == null) { resp.setStatus(404); } else { resp.setContentType("application/json"); resp.getWriter().write(objectMapper.writeValueAsString(user)); } } }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // Handle create user User user = objectMapper.readValue(req.getInputStream(), User.class); userService.save(user); resp.setStatus(201); }}For every URL pattern, you need a separate servlet. No centralized routing, no consistent error handling, no view resolution. DispatcherServlet solves all of this.
Summary
In this post, I explained what DispatcherServlet is and why understanding it matters for Spring Boot developers.
The key points are:
- DispatcherServlet is the front controller—a single entry point that receives all HTTP requests and coordinates the entire request processing pipeline
- It routes requests through HandlerMapping to controllers, invokes methods via HandlerAdapter, and handles view resolution
- Even though Boot auto-configures it, you need to understand it for debugging 404s, configuring filters vs interceptors, and customizing error handling
- The request lifecycle is fixed: Request → DispatcherServlet → HandlerMapping → HandlerAdapter → Controller → Response
- Without understanding DispatcherServlet, you’re flying blind when things break
I recommend learning DispatcherServlet even if you start with Spring Boot. The convenience of auto-configuration is great for productivity, but when something goes wrong, you need to understand the engine under the hood.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 Spring Framework Web MVC Documentation
- 👨💻 Spring MVC Tutorial - Baeldung
- 👨💻 DispatcherServlet Official Reference
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments