Почему Spring не создает бин для класса, аннотированного @Component?

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

Ответ

Если Spring не создает бин для класса с @Component, это указывает на проблему в конфигурации контекста приложения. Основные причины:

  1. Отсутствует или некорректно настроено сканирование компонентов (@ComponentScan). Spring должен знать, в каких пакетах искать аннотированные классы.

    @Configuration
    @ComponentScan(basePackages = "com.example.myapp")
    public class AppConfig {}
    • Класс с @Component должен находиться в пакете com.example.myapp или его подпакетах.
  2. Контекст Spring не инициализирован должным образом. Например, в веб-приложении может отсутствовать DispatcherServlet или инициализатор AbstractAnnotationConfigDispatcherServletInitializer. В standalone-приложении нужно явно создать AnnotationConfigApplicationContext.

    ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
  3. Класс не управляется Spring IoC-контейнером. Создание экземпляра через оператор new обходит механизм Dependency Injection. Для получения бина нужно использовать context.getBean(...) или инжектировать зависимость через @Autowired.

  4. Отсутствуют необходимые зависимости в classpath. Убедитесь, что в pom.xml (Maven) или build.gradle присутствует зависимость spring-context.

  5. Фильтрация при сканировании. В @ComponentScan могут быть указаны фильтры (excludeFilters), которые случайно исключают ваш класс.

Диагностика: При запуске приложения проверьте логи Spring. Сообщения типа "Defining beans..." и "Registered bean definition for ..." подтверждают, что сканирование работает и бин обнаружен.