Как DispatcherServlet в Spring определяет тип найденного контроллера?

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

Ответ

DispatcherServlet определяет тип контроллера через механизм HandlerAdapter. После того как HandlerMapping находит подходящий обработчик (контроллер), сервлет ищет HandlerAdapter, который может с этим обработчиком работать.

Процесс:

  1. Сопоставление: RequestMappingHandlerMapping находит метод контроллера по URL и HTTP-методу (используя аннотации @RequestMapping, @GetMapping и др.).
  2. Адаптация: DispatcherServlet перебирает зарегистрированные HandlerAdapter-ы, вызывая supports(Object handler). Адаптер определяет тип контроллера по его аннотациям и сигнатуре.

Основные типы контроллеров и их адаптеры:

  • @Controller / @RestController: Обрабатывается RequestMappingHandlerAdapter. Возвращаемое значение интерпретируется как имя представления (для @Controller) или напрямую сериализуется в тело ответа (для @RestController).
  • Контроллеры, реализующие интерфейс Controller: Обрабатываются SimpleControllerHandlerAdapter (устаревший подход).
  • HttpRequestHandler: Обрабатывается HttpRequestHandlerAdapter (например, для обработки статических ресурсов).

Пример:

@RestController // Тип контроллера определяется по этой аннотации
public class ApiController {
    @GetMapping("/data")
    public ResponseEntity<String> getData() {
        return ResponseEntity.ok("Response");
    }
}

RequestMappingHandlerAdapter распознает этот класс как контроллер на основе аннотации @RestController и обработает его метод.