@Conditional и @Profile
Оба механизма решают, будет ли зарегистрирован BeanDefinition. Решение принимается при построении контекста, а не при каждом вызове метода.
@Profile
@Configuration
@Profile("dev")
class DevConfiguration {}Профиль — именованная группа конфигурации. Выражения поддерживают логические условия, например prod & !migration.
Активировать профиль можно свойством spring.profiles.active, но лучше, чтобы способ активации был виден в конфигурации окружения. Не следует зашивать production secrets в profile-файл.
@Conditional
@Bean
@ConditionalOnMissingBean(Clock.class)
Clock systemClock() {
return Clock.systemUTC();
}В Spring Boot часто используются:
@ConditionalOnClass;@ConditionalOnMissingBean;@ConditionalOnBean;@ConditionalOnProperty;@ConditionalOnWebApplication.
Порядок имеет значение: condition видит definitions, зарегистрированные к этому моменту. Auto-configuration проектируют так, чтобы пользовательский bean мог её заменить.
Как диагностировать
Если bean отсутствует:
- проверить активные profiles;
- проверить property name, prefix и значение;
- посмотреть condition evaluation report;
- убедиться, что конфигурация импортирована;
- проверить наличие класса и конкурирующего bean;
- не путать «bean не создан» с «bean создан, но proxy другого типа».
Вопросы для повторения
@Profileпроверяется при каждом вызове? Нет, при регистрации контекста.- Чем profile отличается от property condition? Profile — крупная именованная группа, property condition — точное условие настройки.
- Что делает
@ConditionalOnMissingBean? Регистрирует конфигурацию, только если подходящего bean ещё нет. - Можно ли использовать profile для секрета? Нет, профиль выбирает конфигурацию, секрет приходит из защищённого источника.
- Почему условие трудно отлаживать? Результат зависит от classpath, properties, порядка и уже зарегистрированных definitions.
Связано: Профили Sping и Maven, Spring Boot, Основные аннотации Spring.