Ответ
@ComponentScan — это аннотация Spring Framework, которая инструктирует контейнер IoC, где искать классы, помеченные стереотипными аннотациями (такими как @Component, @Service, @Repository, @Controller, @Configuration), чтобы автоматически зарегистрировать их как бины (beans) в контексте приложения.
Основная цель: Автоматическое обнаружение и регистрация компонентов, избавляющее от необходимости ручного объявления каждого бина с помощью @Bean в конфигурационном классе.
Ключевые параметры аннотации:
basePackages/value: Массив имен пакетов для сканирования.@ComponentScan({"com.example.service", "com.example.dao"})basePackageClasses: Массив классов. Пакеты этих классов будут использоваться в качестве отправных точек для сканирования. Это типобезопасная альтернативаbasePackages.@ComponentScan(basePackageClasses = {UserService.class, UserRepository.class})excludeFilters/includeFilters: Позволяют тонко настраивать, какие классы включать или исключать из сканирования, используя аннотации, регулярные выражения и т.д.
Типичное использование:
@Configuration
@ComponentScan("com.example.app") // Сканирует пакет com.example.app и все его подпакеты
public class AppConfig {
// Дополнительные бины, объявленные вручную
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build();
}
}
Важные детали:
- Контекст по умолчанию: Если параметры не указаны, сканирование начинается с пакета, в котором находится класс, помеченный
@ComponentScan. Это часто приводит к ошибкам, если конфигурационный класс лежит в корневом пакете. - Область применения: Аннотация используется на классах, помеченных
@Configurationили непосредственно на главном классе приложения с аннотацией@SpringBootApplication(которая уже содержит в себе@ComponentScan). - Комбинация с ручной конфигурацией:
@ComponentScanможно свободно комбинировать с объявлениями@Beanв одном конфигурационном классе. - Фильтрация: Механизм фильтров (
excludeFilters) часто используется в тестах для исключения определенных конфигураций или замены реальных бинов моками.
Пример с фильтром:
@Configuration
@ComponentScan(
basePackages = "com.example",
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Repository.class // Исключаем все @Repository из сканирования
)
)
public class AppConfig { }