Ответ
DispatcherServlet находит контроллеры через механизм сканирования компонентов Spring (component scanning), который активируется соответствующей конфигурацией.
Необходимые условия:
-
Конфигурация сканирования пакетов:
- Java Config: Использование аннотации
@ComponentScanв классе конфигурации.@Configuration @ComponentScan("com.example.controllers") // Указывает пакет для сканирования @EnableWebMvc // Включает поддержку аннотаций MVC public class WebConfig implements WebMvcConfigurer { // ... } - XML Config: Использование элемента
<context:component-scan>в контексте Spring.<context:component-scan base-package="com.example.controllers"/> <mvc:annotation-driven/>
- Java Config: Использование аннотации
-
Наличие аннотации
@Controller(или@RestController): Класс должен быть помечен этой стереотипной аннотацией, которая является специализацией@Component.@Controller // Будет обнаружен при сканировании пакета "com.example.controllers" public class UserController { // ... } -
Регистрация методов обработчиков: Методы в контроллере должны быть помечены аннотациями маппинга запросов (
@GetMapping,@PostMapping,@RequestMappingи т.д.).
Процесс:
- При старте приложения Spring сканирует указанные пакеты.
- Классы с
@Controllerрегистрируются как бины вApplicationContext. DispatcherServletполучает доступ к этому контексту.- Внутренний компонент
HandlerMapping(по умолчаниюRequestMappingHandlerMapping) индексирует все методы с аннотациями маппинга, связывая URL-шаблоны с конкретными методами контроллеров. - Когда приходит HTTP-запрос,
DispatcherServletзапрашивает уHandlerMappingподходящий обработчик (контроллер + метод) и вызывает его.
Если сканирование не настроено или контроллер находится вне сканируемых пакетов, DispatcherServlet его не обнаружит.
Ответ 18+ 🔞
Слушай, а вот этот твой DispatcherServlet — он же не шарится по всему проекту как угорелый, ища, где бы ему контроллер пристроить. Нет, сука! У него есть чёткий, блядь, механизм — сканирование компонентов (component scanning). Но чтобы эта магия работала, нужно соблюсти три условия, а то нихуя не найдёт, и будешь потом сидеть и чесать репу.
Что нужно, чтобы он их нашёл, этот распиздяй:
-
Настроить сканирование пакетов. А то как он узнает, где искать-то? Есть два пути, оба рабочие:
- Java Config: Тыкаешь в класс конфигурации аннотацию
@ComponentScanи указываешь, где рыть.@Configuration @ComponentScan("com.example.controllers") // Смотри, бля, вот тут ищи! @EnableWebMvc public class WebConfig implements WebMvcConfigurer { // ... } - XML Config: Старая школа, но тоже пашет. Кидаешь в конфиг строку.
<context:component-scan base-package="com.example.controllers"/> <mvc:annotation-driven/>
- Java Config: Тыкаешь в класс конфигурации аннотацию
-
Пометить контроллер правильно. Класс должен быть отмечен аннотацией
@Controller(или@RestController). Это как маячок, блядь! Без неё Spring посмотрит на класс и подумает: "Ну и хуй с тобой, обычный какой-то класс".@Controller // Ага! Вот ты где, сука! Теперь я тебя вижу! public class UserController { // ... } -
Методы-обработчики тоже аннотировать. Ну нашёл он класс, а методы-то какие обрабатывают? Те, что с
@GetMapping,@PostMappingи прочей хуйней.
Как это всё, блядь, работает внутри:
- Приложение стартует, Spring начинает сканировать указанные пакеты, как собака-ищейка.
- Все классы с
@Controllerрегистрируются как бины вApplicationContext. Попали в общую базу, ёпта! - Наш
DispatcherServletимеет доступ к этой базе. - Внутри него
HandlerMapping(чаще всегоRequestMappingHandlerMapping) делает индексацию — связывает URL-шаблоны с конкретными методами в найденных контроллерах. Получается такая карта, блядь, сокровищ. - Прилетает HTTP-запрос.
DispatcherServletлезет в эту карту, находит нужный обработчик (контроллер + метод) и — хуяк! — вызывает его.
А если сканирование не настроил или контроллер в другом пакете лежит, который не указан, то DispatcherServlet пройдёт мимо и даже не моргнёт. Будешь потом думать: "Почему не работает, ёпта?". А потому что, блядь, не настроил!