16
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Spring Boot の application.properties と @Profile アノテーションで環境を切り替える

Last updated at Posted at 2019-06-26

概要

  • Spring Boot でプロファイルを切り替えて実行する
  • プロファイルの指定がない場合は Spring Framework では default プロファイルが使われる
  • 自前のプロファイルとして development, test, production の3つを用意する
  • test と production は一部で同じ要素を使うように構成する
  • プロファイルごとの application-*.properties を用意して、記述した値を使用する
  • @Profile アノテーションを使用して、指定したプロファイルに対応する bean クラスのオブジェクトを DI (Dependency injection) する
  • 複数のプロファイルに対応する bean クラスを用意する
  • 複数のプロファイルを指定した場合に対応する

ソースコード一覧

$ tree src
src
├── main
│   ├── java
│   │   └── info
│   │       └── maigo
│   │           └── lab
│   │               └── sample
│   │                   └── profiles
│   │                       ├── MyData.java
│   │                       ├── MyDataForDefault.java
│   │                       ├── MyDataForDevelopment.java
│   │                       ├── MyDataForTestAndProduction.java
│   │                       ├── MyRestController.java
│   │                       └── ProfilesApplication.java (←今回は中身を省略)
│   └── resources
│       ├── application-development.properties
│       ├── application-production.properties
│       ├── application-test.properties
│       └── application.properties

基本部分のソースコード

MyRestController.java

Spring Framework の DI 機能で MyData のオブジェクトをインジェクションする。
@Autowired アノテーションをインスタンス変数 myData に記述する。
http://localhost:8080/ へアクセスした際に MyData の情報を JSON で返すようにする。

package info.maigo.lab.sample.profiles;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyRestController {

    @Autowired
    private MyData myData;

    @RequestMapping("/")
    public MyData index() {
        return myData;
    }
}

MyData.java

MyData オブジェクトの interface 定義。今回は特にメソッドは用意しない。

package info.maigo.lab.sample.profiles;

public interface MyData {
}

MyDataForDefault.java

default プロファイルで使用する MyData の実装クラス。
@Profile アノテーションで DI するときのプロファイルを指定できる。ここでは default を指定している。
インスタンス変数 profile には文字列 "default" を代入。
インスタンス変数 message には application.properties の message.value を代入。

package info.maigo.lab.sample.profiles;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

@Component
@Profile("default")
public class MyDataForDefault implements MyData {

    public String profile = "default";

    @Value("${message.value}")
    public String message;
}

application.properties

default プロファイルで使用するプロパティファイル。

message.value=Hello, default!

default プロファイルで起動する

ビルドして作った JAR ファイルを指定して起動する。プロファイルを指定するパラメータは付けない。

$ java -jar target/profiles-0.0.1-SNAPSHOT.jar

起動したサーバにアクセスすると default プロファイルの情報が読み込まれているのがわかる。

$ curl http://localhost:8080/
{"profile":"default","message":"Hello, default!"}

development プロファイルで使用するソースコード

MyDataForDevelopment.java

development プロファイルで使用する MyData の実装クラス。
@Profile アノテーションにて develop プロファイルを指定。
インスタンス変数 profile に文字列 "development" を代入。
インスタンス変数 message に application-development.properties の message.value を代入。

package info.maigo.lab.sample.profiles;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

@Component
@Profile("development")
public class MyDataForDevelopment implements MyData {

    public String profile = "development";

    @Value("${message.value}")
    public String message;
}

application-development.properties

development プロファイルで使用するプロパティファイル。

message.value=Hello, development!

development プロファイルを指定して起動する

JVM パラメータ -Dspring.profiles.active に development を指定する。

$ java -Dspring.profiles.active=development -jar target/profiles-0.0.1-SNAPSHOT.jar

起動したサーバにアクセスすると development プロファイルの情報が読み込まれているのがわかる。

$ curl http://localhost:8080/
{"profile":"development","message":"Hello, development!"}

test プロファイルと production プロファイルで使用するソースコード

MyDataForTestAndProduction.java

test プロファイルと production プロファイルで使用する MyData の実装クラス。
@Profile アノテーションに test と production を指定している。指定したいずれかのプロファイルが指定されたときにこのクラスのオブジェクトが DI 対象となる。
@RestController にて返却する JSON の profile は、このクラスの getProfile メソッドにて生成する。Environment#getActiveProfiles で複数指定されたプロファイル名が取得できる。

package info.maigo.lab.sample.profiles;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

@Component
@Profile({"test", "production"})
public class MyDataForTestAndProduction implements MyData {

    @Autowired
    private Environment env;

    public String getProfile() {
        return String.join(",", env.getActiveProfiles());
    }

    @Value("${message.value}")
    public String message;
}

application-test.properties

test プロファイルで使用するプロパティファイル。

message.value=Hello, test!

application-production.properties

production プロファイルで使用するプロパティファイル。

message.value=Hello, production!

test プロファイルを指定して起動する

JVM パラメータ -Dspring.profiles.active に test を指定する。

$ java -Dspring.profiles.active=test -jar target/profiles-0.0.1-SNAPSHOT.jar

起動したサーバにアクセスすると test プロファイルの情報が読み込まれているのがわかる。

$ curl http://localhost:8080/
{"message":"Hello, test!","profile":"test"}

production プロファイルを指定して起動する

JVM パラメータ -Dspring.profiles.active に production を指定する。

$ java -Dspring.profiles.active=production -jar target/profiles-0.0.1-SNAPSHOT.jar

起動したサーバにアクセスすると production プロファイルの情報が読み込まれているのがわかる。

$ curl http://localhost:8080/
{"message":"Hello, production!","profile":"production"}

複数のプロファイル test と production を指定して起動する

JVM パラメータ -Dspring.profiles.active にカンマ区切りで複数のプロファイル "test,production" を指定する。

$ java -Dspring.profiles.active=test,production -jar target/profiles-0.0.1-SNAPSHOT.jar

起動したサーバにアクセスすると、profile 項目の値に "test,production" と入っているため test と production 両方のプロファイルの情報が読み込まれているのがわかる。

$ curl http://localhost:8080/
{"message":"Hello, production!","profile":"test,production"}

application-test.properties と application-production.properties に定義した message.value の値は、競合した結果 application-production.properties の値が優先された (競合すべき値を設定すべきではないと考えられる)。

試しにプロファイル指定の順番を逆にして "production,test" を指定してみたら、application-test.properties の値が優先された。

$ java -Dspring.profiles.active=production,test -jar target/profiles-0.0.1-SNAPSHOT.jar
$ curl http://localhost:8080/
{"message":"Hello, test!","profile":"production,test"}

おそらく、後から指定したプロファイルが優先される (上書きされる?) と思われる。

今回の環境

  • OpenJDK 11
  • Spring Boot 2.2.0.M4

参考資料

16
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?