skip to content

HandlerMapping & Execution Chain

HandlerMapping turns a request into a handler plus its interceptors, with RequestMappingHandlerMapping resolving your @RequestMapping registry. Interviewers ask about mapping ordering and ambiguity when two annotations could match the same URL.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What is a HandlerMapping in Spring MVC, and what does its getHandler method return for an incoming request?

level: juniorimportance: must knowfreq 70%

answer

  1. getHandler → HandlerExecutionChain or null
  2. chain = handler + interceptors
  3. selects, does not invoke
  4. HandlerMethod wraps the @Controller method
  5. DispatcherServlet loops mappings in order

basics

~10 s

A HandlerMapping decides which controller method should handle an incoming HTTP request. Its getHandler method takes the request and returns a HandlerExecutionChain: the chosen handler plus any interceptors that run around it.

solid answer

~40 s

HandlerMapping is the Spring MVC strategy interface that maps an incoming HttpServletRequest to the code that should handle it. The DispatcherServlet asks each registered HandlerMapping, in order, by calling getHandler(request). The first one that can match returns a HandlerExecutionChain — an object bundling the chosen handler (typically a HandlerMethod wrapping a @Controller method) together with the ordered list of HandlerInterceptors that apply to that URL. If no mapping matches, getHandler returns null and the DispatcherServlet moves to the next HandlerMapping; if none match at all, it results in a 404. The handler itself is then invoked via a matching HandlerAdapter — HandlerMapping only chooses; it does not invoke.

code

java · 12 lines
java
// The core strategy interface (simplified)
package org.springframework.web.servlet;

public interface HandlerMapping {
    // Returns the handler + its interceptors, or null if this mapping
    // has nothing for the request (DispatcherServlet then tries the next one).
    HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}

// A HandlerExecutionChain conceptually holds:
//   Object handler                 // e.g. a HandlerMethod for @GetMapping("/users")
//   List<HandlerInterceptor> interceptors  // preHandle/postHandle/afterCompletion

go deeper

for a junior

Know that HandlerMapping picks the controller for a URL and getHandler returns a chain of handler + interceptors.

for a middle

Distinguish select (HandlerMapping) from invoke (HandlerAdapter); know the handler is a HandlerMethod.

for a senior

Explain the null-then-next-mapping loop and the interceptor bundling inside the chain.

for a principal

Frame HandlerMapping as a pluggable strategy enabling multiple handler styles through one uniform dispatch pipeline.

## The problem HandlerMapping solves When an HTTP request arrives, Spring MVC's front controller — the `DispatcherServlet` — must answer one question first: *which piece of my code handles this URL/method?* That decision is delegated to the `HandlerMapping` strategy interface (`org.springframework.web.servlet.HandlerMapping`). ## The single method that matters ```java HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception; ``` - Input: the raw servlet request. - Output: a `HandlerExecutionChain`, or `null` if this particular mapping has nothing for the request. ## HandlerExecutionChain — what's inside A `HandlerExecutionChain` bundles two things: 1. **The handler** — an *opaque* `Object`. For annotation controllers it is a `HandlerMethod` (a wrapper around the specific `@RequestMapping`/`@GetMapping` method and its bean). It is deliberately typed as `Object` so different handler styles (annotated methods, functional endpoints, old `Controller` beans, static resources) can all flow through the same pipeline. 2. **The interceptors** — the ordered list of `HandlerInterceptor` instances whose path patterns match this request. These provide the `preHandle` / `postHandle` / `afterCompletion` hooks that wrap the handler. ## Where it sits in the dispatch flow 1. Request hits `DispatcherServlet.doDispatch`. 2. `getHandler(request)` loops over every registered `HandlerMapping` **in order** and returns the first non-null `HandlerExecutionChain`. 3. `getHandlerAdapter(handler)` finds a `HandlerAdapter` that knows how to *invoke* that handler type. 4. Interceptor `preHandle` methods run; then the handler runs; then `postHandle`; then view rendering; then `afterCompletion`. Key separation of concerns: **HandlerMapping only selects the handler and interceptors. It never invokes the handler** — that is the `HandlerAdapter`'s job. ## What happens when nothing matches If a given `HandlerMapping` returns `null`, the DispatcherServlet tries the next one. If *all* of them return `null`, the DispatcherServlet raises a `NoHandlerFoundException` (or returns a 404 via the default handling), depending on configuration. ## Common concrete implementations - `RequestMappingHandlerMapping` — the modern default; maps annotated `@RequestMapping` methods. - `BeanNameUrlHandlerMapping` — maps URLs to beans whose *name* is a URL path (e.g. bean named `/hello`). - `SimpleUrlHandlerMapping` — explicit URL→handler map, often used for static resources. - `RouterFunctionMapping` — the functional (WebMvc.fn) style. ## Gotchas - The handler is an `Object`, not a controller instance directly — juniors often assume it's the controller bean; for annotation controllers it's actually a `HandlerMethod`. - Returning `null` is normal and expected, not an error — it just means 'not my request, try the next mapping'.

  • For an annotation-based @GetMapping method, what concrete type is the 'handler' inside the chain?
    A HandlerMethod — a wrapper holding the controller bean plus the reflective Method to call. It is not the controller instance itself, and it's typed as Object in the chain so any handler style fits the pipeline.
  • If getHandler returns null, is that an error?
    No. Null just means this mapping doesn't handle the request, so the DispatcherServlet tries the next HandlerMapping. Only if every mapping returns null do you get a 404 / NoHandlerFoundException.

saying these in an interview costs you the question

  • Saying HandlerMapping invokes/runs the controller method (that's HandlerAdapter's job)
  • Thinking the handler in the chain is the controller instance rather than a HandlerMethod
  • Believing a null return means an exception or 404 immediately

context

open as a page

How does RequestMappingHandlerMapping build and use its RequestMappingInfo registry to match a request to a controller method?

level: middleimportance: must knowfreq 60%

basics

~20 s

At startup it scans all @Controller beans, turns each @RequestMapping method into a RequestMappingInfo (path, HTTP method, params, headers, consumes, produces) and stores them in a registry. Per request it finds the RequestMappingInfos that match, picks the most specific one, and returns that HandlerMethod.

open as a page

What is a HandlerExecutionChain, and how do the HandlerInterceptor callbacks it carries execute around the handler — including when a request is short-circuited?

level: seniorimportance: should knowfreq 40%

basics

~20 s

A HandlerExecutionChain pairs the chosen handler with the interceptors that apply to the request. The DispatcherServlet runs each interceptor's preHandle before the handler, postHandle after it (before view rendering), and afterCompletion at the very end. If a preHandle returns false, the request is stopped early.

open as a page

Multiple HandlerMapping beans exist in a Spring MVC app. In what order are they consulted, and how do RequestMappingHandlerMapping and BeanNameUrlHandlerMapping fit into that ordering?

level: seniorimportance: should knowfreq 45%

basics

~20 s

The DispatcherServlet keeps all HandlerMapping beans sorted by their Ordered value (lowest first) and asks each in turn until one returns a non-null chain. RequestMappingHandlerMapping is ordered before BeanNameUrlHandlerMapping, so annotated controllers win over URL-named beans.

open as a page

You need to route requests to different controller methods based on a custom rule (e.g. an API version header) that plain @RequestMapping can't express. How would you extend the HandlerMapping / RequestMappingInfo machinery to do this cleanly?

level: principalimportance: nice to knowfreq 22%

basics

~20 s

Subclass RequestMappingHandlerMapping and override getCustomTypeCondition/getCustomMethodCondition to attach your own RequestCondition (e.g. one that matches an API-Version header). Spring folds it into each RequestMappingInfo, so it participates in matching and specificity ranking alongside the built-in conditions.

open as a page