16. Расскажите про аннотацию @Conditional

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

Все вопросы по теме: список

Все темы: список

Вопросы/замечания/предложения/нашли ошибку: напишите мне

Report Page