Spring Boot 2実戦:条件によって異なる論理のBeanを自動的に配置する


1.はじめに
条件に応じて異なるインタフェースをロードすることがよくあります.例えば、ディレクトリの下のファイルのリストを調べると、Windowsの下ではCMDdirコマンドを使用し、Linuxの下ではlsコマンドを使用します.Spring Bootの自動構成に詳しい人も、Spring Bootが実際の状況に応じて異なる構成を有効にできることを知っています.これが@Conditional注釈が機能している.この注記では、どの条件でBeanを作成して構成するかを指定します.
2.@Conditional注記
Spring Bootは、@Conditional注釈の複数を含み、@Configuration注釈のクラスおよび@Bean注釈の方法で使用することができる.@Conditionalタイプの注釈は、クラスに注釈することができ、Beanメソッドに注釈することができ、Spring Environmentプロパティに基づいて構成を含めることができ、特定のリソースが存在する場合にのみ構成を含めることができる.カスタマイズも可能です.次にSpring Bootが提供する具体的な条件の注釈について説明します.
2.1 Class Conditions @ConditionalOnClass@ConditionalOnMissingClassの2つのクラスでの注記:
指定されたクラスが存在するかどうかを判断して自動構成を構築し、name属性名を使用してクラス名を指定することもできます.
2.2 Bean Conditions @ConditionalOnBean@ConditionalOnMissingBeanの2つのBeanメソッドでの注記:
指定されたBeanが存在するかどうかを判断して自動構成を構築し、value属性を使用してタイプまたは名前(id)でBeanを指定し、search属性指定ApplicationContext階層を使用してBeanを検索できます.
@Configuration
public class MyAutoConfiguration {

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

}

注意Beanを追加する順序を追加するには、ユーザー定義のBeanを追加した後に実行できることを保証するため、自動構成クラスでは@ConditionalOnBean@ConditionalOnMissingBeanのコメントのみを使用することを推奨します.@ConditionalOnBeanおよび@ConditionalOnMissingBean注釈は、@Configuration注釈を含む各方法に作用することに等しい@Bean注釈のクラスに作用する.
2.3 Property Conditions @ConditionalOnProperty注記Spring Environment属性に含まれる構成判断に基づいて、自動構成の実行を決定し、prefixおよびname属性を使用して検査すべき属性を指定することができる.デフォルトでは、falseに等しくない存在する属性と一致します.また、havingValueおよびmatchIfMissingのプロパティを使用して、より高度なチェックを作成することもできます.
2.4 Resource Conditions @ConditionalOnResource注釈では、特定のリソースが存在する場合にのみ自動構成を実行できます.次の例に示すように、一般的なSpring規則を使用してリソースを指定できます:file:/home/user/test.dat.
2.5 Web Application Conditions @ConditionalOnWebApplicationおよび@ConditionalOnNotWebApplication注釈は、アプリケーションがWeb であるかどうかを判断するために使用され、WebアプリケーションはSpring WebApplicationContextを使用してセッション範囲またはStandardServiceletEnvironmentを有する任意のアプリケーションを定義する.
2.6 SpEL Expression Conditions @ConditionalOnExpression注記は、SpEL式の結果に従って構成を実行することを可能にする.
3.カスタム設定
もし上のいくつかがあなたのニーズを満たすことができなければ.では、Conditionインタフェースを実装し、そのmatchesメソッドを書き換えることによって、判断条件を構築することができる.
  • 1.Conditionインタフェースを実装判断条件
  • を定義する.
    //Windows       
    import org.springframework.context.annotation.Condition;
    import org.springframework.context.annotation.ConditionContext;
    import org.springframework.core.type.AnnotatedTypeMetadata;
    
    public class WindowsCondition implements Condition {
    
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return context.getEnvironment().getProperty("os.name").contains("Windows");
        }
    }
    
    
    //Linux       
    import org.springframework.context.annotation.Condition;
    import org.springframework.context.annotation.ConditionContext;
    import org.springframework.core.type.AnnotatedTypeMetadata;
    
    public class LinuxCondition implements Condition {
    
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return context.getEnvironment().getProperty("os.name").contains("Linux");
        }
    }
    
  • 2.異なるシステムにおけるBeanクラス
  • の実装
    //  
    public interface ListService {
        
        public String showListCmd();
    }
    
    //Windows     
    public class WindowsListServiceImpl implements ListService {
    
        @Override
        public String showListCmd() {
            return "dir";
        }
    }
    
    //Linux     
    public class LinuxListServiceImpl implements ListService {
    
        @Override
        public String showListCmd() {
            return "ls";
        }
    }
  • 3.構成クラス
  • @Conditional注記条件判定のクラスを呼び出し、返された結果に基づいてBeanを作成
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Conditional;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class ConditionConfig {
        
        @Bean
        @Conditional(WindowsCondition.class)
        public ListService windowsListService() {
            return new WindowsListServiceImpl();
        }
        
        @Bean
        @Conditional(LinuxCondition.class)
        public ListService linuxListService() {
            return new LinuxListServiceImpl();
        }
    }
  • 4.実行クラス
  •  @RunWith(SpringRunner.class)
     @SpringBootTest
     
     public class SecurityLearningApplicationTests {
     
         @Resource
         private ListService listService ;
         @Resource
         private ApplicationContext context;
     
     
     
     
         public void testCondition(){
             System.out.println(context.getEnvironment().getProperty("os.name")
                     + "        :"
                     + listService.showListCmd());
         }
     
     } 

    4.まとめ
    今日我々はSpring BootにおけるCondition条件判定注入について系統的に理解した.Spring Bootが提供するいくつかの開梱即用のConditionを学習しただけでなく、カスタムのConditionも実現した.Spring Bootの自動構成を深く学習したり、ビジネスに応じて柔軟にカスタマイズしたりするには、Conditionを系統的に学習する必要があります. :Felordcn
    個人ブログ:https://felord.cn