16. Расскажите про аннотацию @Conditional
UNKNOWNЧасто бывает полезно включить или отключить весь класс @Configuration, @Component или отдельные методы @Bean в зависимости от каких-либо условий.
Аннотация @Conditional указывает, что компонент имеет право на регистрацию в контексте только тогда, когда все условия соответствуют. Может применяться:
- над классами прямо или косвенно аннотированными @Component, включая классы @Configuration;
- над методами @Bean;
- как мета-аннотация при создании наших собственных аннотаций-условий.
Условия проверяются непосредственно перед тем, как должно быть зарегистрировано BeanDefinition компонента, и они могут помешать регистрации данного BeanDefinition. Поэтому нельзя допускать, чтобы при проверке условий мы взаимодействовали с бинами (которых еще не существует), с их BeanDefinition-ами можно.
Условия мы определяем в специально создаваемых нами классах, которые должны имплементировать функциональный интерфейс Condition с одним единственным методом, возвращающим true или false:
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata)
Создав свой класс и переопределив в нем метод matches() с нашей логикой, мы должны передать этот класс в аннотацию @Conditional в качестве параметра:
@Configuration
@Conditional(OurConditionClass.class)
class MySQLAutoconfiguration {
//...
}
Для того, чтобы проверить несколько условий, можно передать в @Conditional несколько классов с условиями:
@Bean
@Conditional(HibernateCondition.class, OurConditionClass.class)
Properties additionalProperties() {
//...
}
Если класс @Configuration помечен как @Conditional, то на все методы @Bean, аннотации @Import и аннотации @ComponentScan, связанные с этим классом, также будут распространяться указанные условия.
Для более детальной настройки классов, аннотированных @Configuration, предлагается использовать интерфейс ConfigurationCondition.
В одном классе - одно условие. Для создания более сложных условий можно использовать классы AnyNestedCondition, AllNestedConditions и NoneNestedConditions.
В Spring Framework имеется множество готовых аннотаций (и связанных с ними склассами-условиями, имплементирующими интерфейс Condition), которые можно применять совместно над одним определением бина:
- ConditionalOnBean Условие выполняется, в случае если присутствует нужный бин в BeanFactory.
- ConditionalOnClass Условие выполняется, если нужный класс есть в classpath.
- ConditionalOnCloudPlatform Условие выполняется, когда активна определенная платформа.
- ConditionalOnExpression Условие выполняется, когда SpEL выражение вернуло положительное значение.
- ConditionalOnJava Условие выполняется, когда приложение запущено с определенной версией JVM.
- ConditionalOnJndi Условие выполняется, только если через JNDI доступен определенный ресурс.
- ConditionalOnMissingBean Условие выполняется, в случае если нужный бин отсутствует в контейнере.
- ConditionalOnMissingClass Условие выполняется, если нужный класс отсутствует в classpath.
- ConditionalOnNotWebApplication Условие выполняется, если контекст приложения не является веб контекстом.
- ConditionalOnProperty Условие выполняется, если в файле настроек заданы нужные параметры.
- ConditionalOnResource Условие выполняется, если присутствует нужный ресурс в classpath.
- ConditionalOnSingleCandidate Условие выполняется, если bean-компонент указанного класса уже содержится в контейнере и он единственный.
- ConditionalOnWebApplication Условие выполняется, если контекст приложения является веб контекстом.
Предыдущий вопрос: 15. Как заинжектить коллекцию?
Следующий вопрос: 17. Расскажите про аннотацию @ComponentScan
Все вопросы по теме: список
Все темы: список
Вопросы/замечания/предложения/нашли ошибку: напишите мне