Как DispatcherServlet в Spring определяет, какому контроллеру направить HTTP-запрос?

«Как DispatcherServlet в Spring определяет, какому контроллеру направить HTTP-запрос?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

DispatcherServlet использует стратегии HandlerMapping для сопоставления входящего HTTP-запроса с соответствующим обработчиком (контроллером).

Стандартный процесс маршрутизации:

  1. Получение запроса: DispatcherServlet получает запрос.
  2. Поиск обработчика: Он опрашивает все зарегистрированные реализации HandlerMapping в порядке их приоритета, вызывая метод getHandler(HttpServletRequest request). Первый найденный ненулевой обработчик возвращается.
  3. Сопоставление: По умолчанию RequestMappingHandlerMapping анализирует аннотации в контроллерах (@RequestMapping, @GetMapping, @PostMapping и т.д.) и ищет совпадение по:
    • URL-пути (например, /api/users).
    • HTTP-методу (GET, POST, PUT, DELETE).
    • Параметрам запроса (params).
    • Заголовкам (headers).
    • Content-Type/Accept (consumes/produces).

Пример:

@RestController
@RequestMapping("/api")
public class UserController {
    @GetMapping("/users") // Сопоставляется с GET /api/users
    public List<User> getAllUsers() {
        return userService.findAll();
    }

    @PostMapping("/users") // Сопоставляется с POST /api/users
    public User createUser(@RequestBody User user) {
        return userService.save(user);
    }
}

При запросе GET /api/users RequestMappingHandlerMapping найдет метод getAllUsers() и передаст его как обработчик в DispatcherServlet.