← Назад к вопросам

Всегда ли Spring находит класс, отмеченный аннотацией @Configuration?

1.0 Junior🔥 131 комментариев
#Spring Framework

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Всегда ли Spring находит класс @Configuration

Нет, Spring не всегда находит класс, отмеченный аннотацией @Configuration. Нужны определенные условия для того, чтобы класс был обнаружен и обработан.

Условие 1: Component Scanning должен быть включен

Spring должен сканировать пакеты в поиске компонентов. Это происходит автоматически в Spring Boot, но в обычном Spring нужно явно указать:

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
    @Bean
    public MyService myService() {
        return new MyService();
    }
}

Общая база сканирования — пакет конфигурационного класса и его подпакеты.

Условие 2: Класс должен быть в сканируемом пакете

// Это не будет найдено, если конфиг находится в com.example,
// а этот класс в другом корневом пакете
// com.other.config.MyConfig <- NOT FOUND

@Configuration
public class MyConfig {
    // ...
}

Условие 3: Явная регистрация конфигурации

Если сканирование не помогает, можно явно зарегистрировать класс:

// При инициализации Spring контекста вручную
AnnotationConfigApplicationContext context = 
    new AnnotationConfigApplicationContext(MyConfig.class);

// Или через XML конфиг
<bean class="com.example.MyConfig" />

Условие 4: Класс должен быть на classpath

// Если класс не скомпилирован или не на classpath, 
// Spring его не найдет

Практический пример проблемы

// src/main/java/com/example/config/AppConfig.java
@Configuration
public class AppConfig {
    @Bean
    public DatabaseService databaseService() {
        return new DatabaseService();
    }
}

// src/main/java/com/other/unrelated/LostConfig.java
@Configuration  // Это НЕ будет найдено!
public class LostConfig {
    @Bean
    public CacheService cacheService() {
        return new CacheService();
    }
}

Если основная конфигурация находится в com.example, то LostConfig из com.other не будет обнаружена.

В Spring Boot это проще

В Spring Boot автоматическая конфигурация находит компоненты благодаря @SpringBootApplication:

// Это эквивалентно:
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Оно сканирует пакет приложения и его подпакеты автоматически.

Условие 5: @Configuration может быть условной

Даже если класс найден, он может не активироваться:

@Configuration
@ConditionalOnClass(name = "com.example.SomeClass")
public class ConditionalConfig {
    // Эта конфигурация загружается только если SomeClass в classpath
}

@Configuration
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
public class FeatureConfig {
    // Загружается только если feature.enabled=true в application.properties
}

Решение: явное указание

Если вы не уверены, лучше явно указать:

@SpringBootApplication(scanBasePackages = {
    "com.example.config",
    "com.example.service",
    "com.other.modules"
})
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Проверка в тестах

@SpringBootTest
public class ConfigTest {
    @Autowired
    private ApplicationContext context;
    
    @Test
    public void shouldLoadConfig() {
        assertTrue(context.containsBean("databaseService"));
        // Если бин не найден, тест упадет с ошибкой
    }
}

Итог

Spring найдет @Configuration класс только если:

  1. Component scanning включен
  2. Класс находится в сканируемом пакете
  3. Класс на classpath
  4. Условные аннотации (если есть) выполнены
  5. Класс явно зарегистрирован (если сканирование не работает)

В Spring Boot это обычно работает «из коробки» для классов в пакетах вашего приложения.