SpringBootでのcondition注記の使用

11407 ワード

プロジェクトでは、コンフィギュレーション、Bean、Serviceなどのbeanコンポーネントを必要とする場合があります.Springbootでは、条件付き注入を処理するための一連の@Condition*注釈が提供されています.

1.説明


Spring 4に@Condition annotationが追加され、このAnnotationを使用した後、依存注入を行うと、ある条件が満たされているかどうかを検出してクラスを注入するかどうかを決定します.Springbootはspring 4のこの注釈に基づいて判断のための複数の条件注釈を実現し、使用中にこれらの注釈が私たちの要求を満たすことができなければ@Conditionalカスタム条件注釈を使用することもできます.

2.一般的な条件注記


じょうけん注記
対応するCondition処理クラス
プロセスロジック
@ConditionalOnBean
OnBeanCondition
Springコンテナに対応するインスタンスが存在するかどうか.インスタンスのタイプ、クラス名、注釈、ニックネームでコンテナを検索できます(現在のコンテナから検索するか、親コンテナから検索するか、両方を一緒に検索するように構成できます).
@ConditionalOnClass
OnClassCondition
クラスローダに対応するクラスが存在するかどうか.クラス指定(valueプロパティ)またはクラスのフルネーム指定(nameプロパティ)複数のクラスまたは複数のクラス名の場合、関係は「与」関係、すなわちこれらのクラスまたはクラス名は同時にクラスローダに存在する必要があります.
@ConditionalOnExpression
OnExpressionCondition
SpEL式が成立するか否かを判定する
@ConditionalOnMissingBean
OnBeanCondition
Springコンテナに対応するインスタンスがないかどうか.インスタンスのタイプ、クラス名、注釈、ニックネームでコンテナを検索できます(現在のコンテナから検索するか、親コンテナから検索するか、両方を一緒に検索するように構成できます).
@ConditionalOnMissingClass
OnClassCondition
ConditionalOnClassの処理ロジックと同様に,条件が逆であるだけでクラスローダには対応するクラスは存在しない.
@ConditionalOnProperty
OnPropertyCondition
アプリケーション環境のプロパティが存在するかどうか.prefix、name、havingValue、およびmatchIfMissingプロパティを指定します.prefixは属性名の接頭辞を表し、nameは属性名、havingValueは具体的な属性値、matchIfMissingはboolean値であり、属性が存在しない場合、このmatchIfMissingはtrueであれば検証を続け、そうでなければ属性が存在しない場合はマッチングが成功しないことに相当する
@ConditionalOnResource
OnResourceCondition
指定したリソースファイルが存在するかどうか.プロパティresourcesは1つだけで、String配列です.クラス・ローダから対応するリソース・ファイルが存在するかどうかをクエリーします.
@ConditionalOnSingleCandidate
OnBeanCondition
Springコンテナに存在するかどうか、対応するインスタンスは1つしか存在しません.属性value、type、searchは3つしかありません.ConditionalOnBeanの3つの属性値の意味と同じです
@ConditionalOnWebApplication
OnWebApplicationCondition
アプリケーションがWebプログラムであるかどうかは、属性が提供されておらず、識別されているだけです.Webプログラム特有のクラスが存在するかどうか,環境がサーブレット環境であるかどうか,コンテナがWebコンテナであるかどうかなどを判断する.

例を挙げる



説明
@ConditionalOnBean(javax.sql.DataSource.class)
Springコンテナまたはすべての親コンテナに少なくとも1つのjavaxが存在する必要がある.sql.DataSourceクラスのインスタンス
@ConditionalOnClass({ Configuration.class,FreeMarkerConfigurationFactory.class })
クラスローダには、コンフィギュレーションとFreeMarkerコンフィギュレーションファクトリの2つのクラスが存在する必要があります.
@ConditionalOnExpression(“’${server.host}’==’localhost’”)
server.ホスト構成項目の値はlocalhostである必要があります
ConditionalOnJava(JavaVersion.EIGHT)
Javaバージョンは少なくとも8
@ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
Spring現在のコンテナにErrorControllerタイプのbeanは存在しません
@ConditionalOnMissingClass(“GenericObjectPool”)
クラスローダにGenericObjectPoolというクラスは存在しません
@ConditionalOnNotWebApplication
非Webアプリケーションで有効にする必要があります
@ConditionalOnProperty(prefix = “spring.aop”, name = “auto”, havingValue = “true”, matchIfMissing = true)
アプリケーションの環境にspringが必要です.aop.autoという構成で、その値がtrueまたは環境にspringは存在しない.aop.AutoConfiguration(matchIfMissingはtrue)
@ConditionalOnResource(resources=”mybatis.xml”)
クラスのロードパスにmybatisが存在する必要があります.xmlファイル
@ConditionalOnSingleCandidate(PlatformTransactionManager.class)
Spring現在または親コンテナにPlatformTransactionManagerというタイプのインスタンスが存在する必要があります.インスタンスは1つのみです.
@ConditionalOnWebApplication
Webアプリケーションで有効になる必要があります

3.カスタム条件注記


条件付き注釈を実現するには2つのクラスが必要です
  • カスタム注釈クラス定義注釈、判断用の条件クラス
  • を指定する.
  • 条件クラス実現org.springframework.context.annotation.Conditionインタフェース、判定条件
  • を定義する
    例:1.注釈クラスの定義MyConditionalOnProperty注釈@Conditional(MyOnPropertyCondition.class)を使用するには、MyOnPropertyConditionが定義する条件クラスです.
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE, ElementType.METHOD})
    @Documented
    @Conditional(MyOnPropertyCondition.class)
    public @interface MyConditionalOnProperty {
        String value();
        String prefix() default "";
        String havingValue() default "";
        boolean matchIfMissing() default false;
        boolean relaxedNames() default true;
        //TODO ADD ONE PROPERTY
        String havingValue() default "";
    }
    

    2.条件クラスの定義:
    public class MyOnPropertyCondition implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(MyConditionalOnProperty.class.getName());
            String propertyName = (String) annotationAttributes.get("value");
            String value = annotationAttributes.get("havingValue");
            String propertyValue = context.getEnvironment().getProperty(propertyName);
           
            if (propertyValue.equalsIgnoreCase(value)) {
                return true;
            }
            return false;
        }
    }
    

    3.呼び出し
       @Configuration
        public class MyConfig {
            @Bean
            @MyConditionalOnProperty(value = "env",havingValue = "dev")
            public Person person(){
                log.info(" Bean");
                return new Person();
            }
        }