Spring Bootにおける条件付きBeanの有効化: @ConditionalOnPropertyアノテーションの活用

@ConditionalOnPropertyによる条件付きBeanの定義

Spring Bootアプリケーションでは、特定の条件に基づいてBeanを登録したり、設定クラスを有効にしたりすることができます。その中でも、アプリケーションのプロパティ値に基づいてコンポーネントの有効/無効を切り替える際に非常に便利なのが@ConditionalOnPropertyアノテーションです。

このアノテーションは、指定されたプロパティが存在し、かつその値が期待される値と一致する場合にのみ、関連するBeanや@Configurationクラスをロードします。プロパティが存在しない場合や、値が一致しない場合には、それらのコンポーネントはアプリケーションコンテキストに登録されません。

基本的な使用例

例えば、特定の機能の有効/無効をアプリケーションプロパティで制御したい場合を考えます。まず、application.properties(またはapplication.yml)に次のようなプロパティを定義します。

app.feature.enabled=true

次に、このプロパティに基づいてBeanの生成を制御する設定クラスを作成します。

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;

@Configuration
@ConditionalOnProperty(
    prefix = "app.feature",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = false
)
public class FeatureActivationConfiguration {

    // このサービスは 'app.feature.enabled=true' の場合にのみBeanとして登録されます
    @Bean
    public MyFeatureService myFeatureService() {
        return new MyFeatureService();
    }

    public static class MyFeatureService {
        public String getFeatureStatus() {
            return "特定機能サービスが有効になりました。";
        }
    }
}

上記の例では、app.feature.enabledというプロパティが存在し、その値が"true"である場合にのみ、FeatureActivationConfigurationクラス全体が有効になり、myFeatureServiceというBeanがSpringコンテキストに登録されます。

条件付きBeanの利用

この条件付きで登録されるサービスをアプリケーション内で利用する際は、通常通りDI (Dependency Injection) を行います。ただし、Beanが登録されない可能性を考慮し、存在チェックや@Autowired(required = false)を使用することが望ましいです。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

@SpringBootApplication
public class PropertyConditionalApplication {

    public static void main(String[] args) {
        SpringApplication.run(PropertyConditionalApplication.class, args);
    }

    @Component
    public static class ApplicationStartupRunner implements CommandLineRunner {

        private final ApplicationContext applicationContext;

        @Autowired
        public ApplicationStartupRunner(ApplicationContext applicationContext) {
            this.applicationContext = applicationContext;
        }

        @Override
        public void run(String... args) {
            // MyFeatureServiceがBeanとして存在するか確認
            if (applicationContext.containsBean("myFeatureService")) {
                FeatureActivationConfiguration.MyFeatureService service =
                    applicationContext.getBean(FeatureActivationConfiguration.MyFeatureService.class);
                System.out.println(service.getFeatureStatus());
            } else {
                System.out.println("特定機能サービスは現在無効です。");
            }
        }
    }
}

このコードを実行すると、application.propertiesapp.feature.enabled=trueが設定されていれば「特定機能サービスが有効になりました。」と出力され、それ以外の場合は「特定機能サービスは現在無効です。」と出力されます。

@ConditionalOnPropertyアノテーションの主要属性

  • prefix: プロパティ名のプレフィックスを指定します。例えば「app.feature」のように指定すると、後のname属性で指定するプロパティが「app.feature.enabled」のように解決されます。
  • name: 条件を適用するプロパティのキーを指定します。prefixと組み合わせて完全なプロパティ名が形成されます。複数のプロパティ名を指定することも可能です。
  • havingValue: プロパティ値がこの値と一致する場合にBeanが作成されます。値が指定されない場合(デフォルト)、プロパティが存在し、その値が"false"ではない場合にBeanが作成されます。
  • matchIfMissing: trueに設定すると、指定されたプロパティが存在しない場合でもBeanが作成されます。デフォルトはfalseです。

その他の条件付きアノテーション

Spring Bootには、@ConditionalOnProperty以外にも様々な条件付きアノテーションが用意されています。これらを活用することで、さらに柔軟なコンポーネントの条件付きロードが可能です。

  • @ConditionalOnClass
  • @ConditionalOnMissingClass
  • @ConditionalOnBean
  • @ConditionalOnMissingBean
  • @ConditionalOnResource
  • @ConditionalOnWebApplication
  • @ConditionalOnNotWebApplication
  • @ConditionalOnJava
  • @ConditionalOnExpression
  • @ConditionalOnJndi
  • @ConditionalOnCloudPlatform
  • @ConditionalOnSingleCandidate

タグ: Spring Boot Java 条件付きBean 設定 プロパティ

7月21日 21:15 投稿