Spring BootでWARを作成して別のTomcatにデプロイするでも書いた通り、開発中はSpring Bootの組み込みTomcatを使って開発するが、テスト環境や本番環境では予め用意されている別のTomcatにWARをデプロイして動作させる、なんてケースがあると思います。その時のapplication.propertiesってどうしていますか?という話です。
例えば、dev1~dev3という環境があるとします。dev1にはdev1の設定(DBの接続先やスキーマ等)を持っているapplication.propertiesを、dev2にはdev2の設定を持っているapplication.propertiesを、dev3にはdev3の設定を持っているapplication.propertiesをビルド時にWARに含めちゃえばいいと思いませんか?
Spring Bootのprofile機能では実現できない
一般的にSpring Bootのapplication.properties周りの構成は以下のような感じになっています。
試しにこの状態で以下2つのやり方で試してみます。
Spring Boot起動時のprofile機能を利用してみる
Spring Bootでは以下のようにすることで動的にprofileを切り替える仕組みがあります。公式ではちょうどこの部分で語られています。
java -jar -Dspring.profiles.active=dev1 spring-boot-application-properties-1.0.0.jar
ただし、これはあくまでSpring Bootの組み込みTomcatを使ったTomcat起動時の話です。成果物であるjarをjavaコマンドで実行する、という前提があります。この場合、環境ごとに以下のようなコマンドを予め用意しておくだけで事足ります。
dev1という環境で動作させる場合
java -jar -Dspring.profiles.active=dev1 spring-boot-application-properties-1.0.0.jar
dev2という環境で動作させる場合
java -jar -Dspring.profiles.active=dev2 spring-boot-application-properties-1.0.0.jar
dev3という環境で動作させる場合
java -jar -Dspring.profiles.active=dev3 spring-boot-application-properties-1.0.0.jar
タイトルにもある通り「WARに含めるapplication.propertiesを環境ごとにビルド時に切り替える」とは別の話なので、上記では実現できません。
application.propertiesのspring.profiles.active=XXXを利用してみる
spring.profiles.active=dev1
これであれば切り替えは出来そうです。
ただし、「WARに含めるapplication.propertiesを環境ごとにビルド時に切り替える」という点では、動的にactiveを切り替えることができないため、デプロイしたい環境が変わる度にapplication.propertiesのspring.profiles.active=のところを修正してコミットしてビルドしなおす必要あります(dev2という環境にデプロイしたい場合、spring.profiles.active=dev2に修正してコミットが必要、dev3でも同じことが言える)。
どうするか?
こんな時はMavenのprofile機能を使って解決します。
以下のように、「src/環境識別子/resources」の構成でディレクトを作成し、それぞれの環境の設定を記載したapplication.propertiesを配置します。
# dev1 environment setting
# dev2 environment setting
# dev3 environment setting
次に、以下のようにpom.xmlにprofileを記載します。
<profiles>
<profile>
<id>dev1</id> // ←環境識別子
<build>
<resources>
<resource>
<directory>src/dev1/resources</directory>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</profile>
<profile>
<id>dev2</id> // ←環境識別子
<build>
<resources>
<resource>
<directory>src/dev2/resources</directory>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</profile>
<profile>
<id>dev3</id> // ←環境識別子
<build>
<resources>
<resource>
<directory>src/dev3/resources</directory>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</profile>
</profiles>
※mavenのprofileについてはMaven3で環境ごとのresourceを差分で管理する方法を参考にしてもらえたらと思います。
最後に、以下のように-Pオプションに環境識別子(pom.xmlのid属性に指定した値、ここではdev1とかdev2とかdev3がそれにあたる)を指定してビルドします(WARファイルを作成します)。
mvn package -Pdev1 spring-boot:repackage
出来たWARを確認してみると、application.propertiesが1つだけになっていることが分かります。また、中身を確認すると-Pオプションで指定した環境識別子(ここではdev1)のresources配下のapplication.propertiesがWARに含まれていることもわかります。
dev2にデプロイしたい場合は、以下のようにするだけです。
mvn package -Pdev2 spring-boot:repackage
こうすることで、今度はsrc/dev2/resources/application.propertiesがWARに含まれます。
結論
Spring Bootの話かと思いきやMavenの話っぽくなってしまいましたが、Mavenのprofile機能を使えば可能です。