【Spring】プロファイルに応じてインジェクションする実装クラスを切り替える

概要

Spring Bootで構築したアプリケーションにおいて、プロファイルの設定に応じてインジェクションされる実装クラスを切り替える方法を紹介します。

実行環境は以下の通りです。

  • Java 17
  • Spring Boot 2.6.7

インジェクション対象のクラスに@Profileを指定する

Interfaceを定義し、実装クラスに@Profileアノテーションでプロファイルを指定することでプロファイルに応じてインジェクションされる実装クラスを変更することができます。

以下のようにInterfaceを定義します。

public interface GreetingService {
    String greet();
}

実装クラスを2つ定義します。開発環境と本番環境でサービスクラスを切り替えるイメージです。

// importは省略

@Profile("default | dev")
@Primary
@Service
public class GreetingServiceImpl1 implements GreetingService {
    @Override
    public String greet() {
        return "This is the development environment.";
    }
}
// importは省略

@Profile("prd")
@Service
public class GreetingServiceImpl2 implements GreetingService {

    @Override
    public String greet() {
        return "This is the production environment.";
    }
}

プロファイルが"dev"の場合はGreetingServiceImpl1、"prd"の場合はGreetingServiceImpl2が使用されます。

プロファイルが何も指定されない場合は"default"となります。今回はプロファイルが指定されない場合は開発環境用のサービスクラスを使用するという想定で GreetingServiceImpl1を@Profile(“default | dev")としました。仮に"default"の指定が無い場合は、プロファイルが指定されない場合はインジェクション対象が存在しなくなるのでSpring Bootアプリケーションの起動時にエラーとなります。

プロファイを"dev,prd"のように指定された場合は"dev"を優先させるという想定でGreetingServiceImpl1に@Primaryを付与しています。@Primaryを指定していない場合、インジェクション対象の実装クラスを1つに限定できないためSpring Bootアプリケーションの起動時にエラーとなります。

今回は技術検証のために"default"、@PrimaryをGreetingServiceImpl1に付与しています。実際のアプリケーションにおいては、"dev,prd"のように想定外のプロファイルがしてされた場合には起動時にエラーとした方が安全だと思います。