Зачем нужны @Conditional и ConditionalOn... аннотации в Spring Boot?
- Как сделать бин, который создаётся только при условии?
@Conditional создаёт бин или конфигурацию только при выполнении условия. На этом построена вся автоконфигурация Spring Boot: @ConditionalOnClass, @ConditionalOnMissingBean, @ConditionalOnProperty, @ConditionalOnBean.
- OnMissingBean — «по умолчанию, если пользователь не задал свой»
- OnProperty — включение функции флагом в настройках
- Условия на OnBean зависят от порядка обработки — использовать в автоконфигурациях с @AutoConfiguration(after=…)
А ещё @Profile — частный случай условия
Подробно
Базовый механизм: @Conditional(MyCondition.class) и класс, реализующий Condition.matches(context, metadata). Если false, бин или вся @Configuration не регистрируются.
Готовые условия Spring Boot:
@ConditionalOnClass/OnMissingClass— есть ли класс на classpath (библиотека подключена);@ConditionalOnBean/@ConditionalOnMissingBean— есть ли бин такого типа; второе — основа переопределения: «создам ObjectMapper, только если вы не создали свой»;@ConditionalOnProperty(name = "features.reports.enabled", havingValue = "true")— включение по настройке;@ConditionalOnWebApplication,@ConditionalOnResource,@ConditionalOnExpression,@ConditionalOnJava,@ConditionalOnCloudPlatform.
**Подводный камень OnBean:** условие проверяется в момент обработки конфигурации. Если нужный бин регистрируется позже, условие не сработает. Поэтому в пользовательских @Configuration его избегают, а в автоконфигурациях задают порядок (@AutoConfiguration(after = DataSourceAutoConfiguration.class)).
Отладка: отчёт условий — --debug или /actuator/conditions.
Пример
@Configuration
class ReportsConfig {
@Bean
@ConditionalOnProperty(prefix = "features.reports", name = "enabled", havingValue = "true")
ReportScheduler reportScheduler() { return new ReportScheduler(); }
}Что хотят услышать
- Механизм @Conditional.
- Готовые условия Spring Boot и их роль в автоконфигурации.
- Подводный камень OnBean и порядок.
Частые ошибки
- Использовать @ConditionalOnBean в обычной конфигурации и удивляться, что бин не создаётся.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Чтобы условно применять транзакции к методам в зависимости от аргументов
- ✓Бин создаётся только при выполнении условия
- ✗Чтобы задать порядок вызова бинов одного типа при внедрении списком в другой компонент приложения
- ✗Для валидации входных DTO по условиям, заданным в аннотациях полей
Что спросят дальше
- Что делает @ConditionalOnMissingBean?
- Как посмотреть condition evaluation report?
Разбор темы
- Spring Boot: автоконфигурация и starters
@SpringBootApplication и starters, механизм автоконфигурации по условиям, переопределение через @ConditionalOnMissingBean, внешняя конфигурация и её приоритеты.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.