Какие есть варианты Conditional аннотаций в Spring
Что проверяют
Понимаете ли вы, как устроена автоконфигурация Spring Boot, а не только помните список аннотаций. Важно различать базовый механизм Spring Framework и готовые условия Boot. Следом обычно спрашивают, почему @ConditionalOnBean в своей конфигурации иногда не срабатывает, или просят написать собственное условие.
Как отвечать
Основа это @Conditional из Spring Framework: он принимает класс, реализующий Condition с методом matches(ConditionContext, AnnotatedTypeMetadata). На нём же построен @Profile. Остальное это готовые условия Spring Boot:
@ConditionalOnClass,@ConditionalOnMissingClass: наличие класса в classpath, на этом держатся стартеры;@ConditionalOnBean,@ConditionalOnMissingBean: есть ли бин нужного типа или имени.@ConditionalOnMissingBeanпозволяет пользователю подменить бин по умолчанию своим;@ConditionalOnProperty: значение свойства. БезhavingValueсрабатывает, если свойство задано и не равноfalse, аmatchIfMissingпо умолчаниюfalse;@ConditionalOnWebApplication,@ConditionalOnNotWebApplication: тип приложения, сервлетное или реактивное;@ConditionalOnExpression: произвольное выражение SpEL, гибко, но плохо читается;@ConditionalOnJava,@ConditionalOnSingleCandidate,@ConditionalOnCloudPlatform: версия JVM, единственный кандидат среди бинов, платформа вроде Kubernetes.
Своё условие удобно наследовать от SpringBootCondition: причина срабатывания попадёт в отчёт, который выводится при запуске с --debug и доступен через /actuator/conditions. Тестировать автоконфигурацию удобно через ApplicationContextRunner.
Где спотыкаются
Не разделяют Spring и Spring Boot: без Boot @ConditionalOnProperty нет, пишут свой Condition.
Ставят @ConditionalOnBean в обычную пользовательскую конфигурацию. Условие смотрит на уже зарегистрированные бины, и результат зависит от порядка обработки. Документация советует применять его только в автоконфигурации.
Вешают @ConditionalOnClass на метод, у которого этот класс в сигнатуре. Если класса нет, конфигурация может упасть ещё при загрузке, надёжнее условие на уровне класса или атрибут name.