Spring Boot: создание собственной автоконфигурации, аннотации условий

Вы почти всегда захотите включить одну или несколько аннотаций @Conditional в свой класс автоконфигурации. Аннотация @ConditionalOnMissingBean - это один из распространенных примеров, который позволяет разработчикам переопределять автоконфигурацию, если они недовольны вашими настройками по умолчанию.

Spring Boot включает в себя ряд аннотаций @Conditional, которые вы можете повторно использовать в своем собственном коде, аннотируя классы @Configuration или отдельные методы @Bean. Эти аннотации включают в себя:

  • Class Conditions (Условия класса)
  • Bean Conditions (Условия компонента)
  • Property Conditions (Условия свойства)
  • Resource Conditions (Условия ресурса)
  • Web Application Conditions (Условия веб-приложения)
  • SpEL Expression Conditions (Условия выражения SpEL)

Условия класса

Аннотации @ConditionalOnClass и @ConditionalOnMissingClass позволяют включать классы @Configuration в зависимости от наличия или отсутствия определенных классов. Из-за того, что метаданные аннотации анализируются с помощью ASM, вы можете использовать атрибут value для ссылки на реальный класс, даже если этот класс может фактически не отображаться в пути к классу запущенного приложения. Вы также можете использовать атрибут name, если предпочитаете указывать имя класса, используя строковое значение.

Этот механизм не применяется таким же образом к методам @Bean, где тип возвращаемого значения является целью условия: перед применением условия к методу JVM загрузит класс и потенциально обработанные ссылки на методы, которые завершатся неудачно, если класса нет.

Для обработки этого сценария отдельный класс @Configuration может использоваться для изоляции условия, как показано в следующем примере:

@Configuration(proxyBeanMethods = false)
// Некоторые условия
public class MyAutoConfiguration {

    // Автоматически настренные компоненты

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnClass(EmbeddedAcmeService.class)
    static class EmbeddedConfiguration {

        @Bean
        @ConditionalOnMissingBean
        public EmbeddedAcmeService embeddedAcmeService() { ... }

    }

}

Если вы используете @ConditionalOnClass или @ConditionalOnMissingClass как часть метааннотации для составления ваших собственных составных аннотаций, вы должны использовать name, так как ссылка на класс в таком случае не обрабатывается.

Условия компонента

Аннотации @ConditionalOnBean и @ConditionalOnMissingBean позволяют включать компонент на основе наличия или отсутствия определенных компонентов. Вы можете использовать атрибут value для указания bean-компонентов по типу или name чтобы указать bean-компоненты по имени. Атрибут search позволяет вам ограничить иерархию ApplicationContext, которая должна учитываться при поиске bean-компонентов.

При размещении в методе @Bean целевым типом по умолчанию является тип возвращаемого значения метода, как показано в следующем примере:

@Configuration(proxyBeanMethods = false)
public class MyAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public MyService myService() { ... }

}

В предыдущем примере bean-компонент myService будет создан, если в ApplicationContext уже не содержится bean-компонент типа MyService.

Вы должны быть очень осторожны с порядком, в котором добавляются определения bean-компонентов, так как эти условия оцениваются на основе того, что уже обработано. По этой причине рекомендуется использовать только аннотации @ConditionalOnBean и @ConditionalOnMissingBean в классах автоконфигурации (поскольку они гарантированно загружаются после добавления любых определенных пользователем определений компонентов).

@ConditionalOnBean и @ConditionalOnMissingBean не препятствуют созданию классов @Configuration. Единственная разница между использованием этих условий на уровне класса и маркировкой каждого содержащегося метода @Bean аннотацией состоит в том, что первый предотвращает регистрацию класса @Configuration в качестве компонента, если условие не совпадает.

Условия свойства

Аннотация @ConditionalOnProperty позволяет включать конфигурацию на основе свойства Spring Environment. Используйте атрибуты prefix и name, чтобы указать свойство, которое следует проверять. По умолчанию любое свойство, которое существует и не равно false, сопоставляется. Вы также можете создавать более сложные проверки, используя атрибуты havingValue и matchIfMissing.

Условия ресурса

Аннотация @ConditionalOnResource позволяет включать конфигурацию только при наличии определенного ресурса. Ресурсы могут быть указаны с использованием обычных соглашений Spring, как показано в следующем примере: file:/home/user/test.dat.

Условия веб-приложения

Аннотации @ConditionalOnWebApplication и @ConditionalOnNotWebApplication позволяют включать конфигурацию в зависимости от того, является ли приложение «веб-приложением» (“web application”). Веб-приложение на основе сервлетов - это любое приложение, которое использует Spring WebApplicationContext, определяет область сеанса (session scope) или имеет ConfigurableWebEnvironment. Реактивное веб-приложение - это любое приложение, которое использует ReactiveWebApplicationContext или имеет ConfigurableReactiveWebEnvironment.

Условия выражения SpEL

Аннотация @ConditionalOnExpression позволяет включать конфигурацию на основе результата SpEL выражения.


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки