Spring BootでWARに含めるapplication.propertiesを環境ごとにビルド時に切り替える

[Spring BootでWARを作成して別のTomcatにデプロイする](http://qiita.com/ARS_2000/items/3f191aeb6f161101d5f6)でも書いた通り、開発中は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周りの構成は以下のような感じになっています。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/23101/dabc887f-123b-b085-f056-9559ef96aecf.png)

試しにこの状態で以下2つのやり方で試してみます。

### Spring Boot起動時のprofile機能を利用してみる

Spring Bootでは以下のようにすることで動的にprofileを切り替える仕組みがあります。公式ではちょうど[この部分](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html)で語られています。

```
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を利用してみる

```application.properties
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を配置します。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/23101/c6058b4b-a64b-ac39-b790-78f07e4cbfdd.png)
ここでは便宜的に以下のようにしました。

```src/dev1/resources/application.properties
# dev1 environment setting
```

```src/dev2/resources/application.properties
# dev2 environment setting
```

```src/dev3/resources/application.properties
# dev3 environment setting
```

次に、以下のようにpom.xmlにprofileを記載します。

```pom.xml
<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を差分で管理する方法](http://qiita.com/sh-ogawa/items/8be83bd44e3c999f7cd6)を参考にしてもらえたらと思います。

最後に、以下のように-Pオプションに環境識別子(pom.xmlのid属性に指定した値、ここではdev1とかdev2とかdev3がそれにあたる)を指定してビルドします(WARファイルを作成します)。

```ビルドしてwarファイルを作成する.
mvn package -Pdev1 spring-boot:repackage
```

出来たWARを確認してみると、application.propertiesが1つだけになっていることが分かります。また、中身を確認すると-Pオプションで指定した環境識別子(ここではdev1)のresources配下のapplication.propertiesがWARに含まれていることもわかります。

dev2にデプロイしたい場合は、以下のようにするだけです。

```dev2へデプロイのためのビルド.
mvn package -Pdev2 spring-boot:repackage
```

こうすることで、今度はsrc/dev2/resources/application.propertiesがWARに含まれます。

# 結論
Spring Bootの話かと思いきやMavenの話っぽくなってしまいましたが、Mavenのprofile機能を使えば可能です。