Spring Bootでは、プロファイルという機能を用いて、設定値をyaml
ファイルやpropeties
ファイルとして外部に切り分けることができます。
これを使って、実行環境ごとの定数値をまとめたり、DIされるクラスを変えたりすることができます。
今回はyaml
の例で解説します。properties
でも形式以外同じです。
基本
src/main/resources/
にapplication.yml
を配置すると、デフォルトでそこに記述した設定値がロードされます。
spring: thymeleaf: cache: false
ここで、記述した値は上書きされない限り、どの環境でも同じです。
各環境の設定ファイルは、application-xxx.yml
という名前でファイルを作ると、プロファイルとして自動で参照できるようになります。
(明示的にプロファイル名をファイル内に記述する方法もあります。)
application-dev.yml
という名前のファイルを用意した場合、プロファイル名は、dev
になります。
こちらをデフォルトのプロファイルとして指定する場合は、application.yml
に以下のように記述します。
spring: profiles: active: dev
実行時に読み込むプロファイルの指定
System Properties
やコマンドライン引数や、環境変数で設定できます。
jar
起動の場合、
# Java System Properties java -jar -Dspring.profiles.active=prod hoge.jar # コマンドライン引数 java -jar hoge.jar --spring.profiles.active=prod
です。
環境変数の場合は、SPRING_PROFILES_ACTIVE
を設定します。
(IntelliJ Ultimateなど一部のIDEでは、GUIから指定できます)
クラスを環境ごとに切り替える
@Profile
を使うと、指定したプロファイルが有効な時に、そのクラスがロードされます。
例えば、prod
とdev
の場合に使う、それぞれHoge
というインタフェースを実装する、HogeDev
、HogeProd
の2つのクラスを用意したい場合、
@Profile("dev") public final class HogeDev implements Hoge { ... } @Profile("prod") public final class HogeProd implements Hoge { ... }
のようになります。
また、@Profile("{dev, prod}")
のように、複数のプロファイルを指定することもできます。
値を切り替える
プロパティにプロファイルから読んだ値を設定したい場合、@Value
を利用します。
例えば、試験環境と本番環境のAPIのアドレスを変えたい時は、
@Value("${api.endpoint}") private String endpoint;
api: endpoint: http://localhost:3000/v1/
と書くと、初期値としてyaml
から読まれた値が設定されます。
Spring BootのDIコンテナを使う
Spring Bootの@Autowired
は、インターフェースにも利用できます。
その場合、実装が1つならばうまく注入してくれるので、先ほどの@Profile
を利用して実装します。
public final class HogeGovernor { @Autowired private Hoge hoge; }
@Component @Profile("prod") public final class HogeProd implements Hoge { ... }
このようにすると、スッキリ実装を切り替えることができます。
テストでもプロファイルを使う
ユニットテスト時には、@ActiveProfiles
を用いることで、有効なプロファイルを指定することができます。(複数も可)
@ActiveProfiles("dev") public final class HogeTest { ... }
こうすることで、各テストケースの実行時にはdev
プロファイルが読み込まれた状態となります。