エキサイト株式会社メディア事業部エンジニアの佐々木です。SpringBootのMulti Module構成を採用して、各プロダクトごとにモノリポでモジュラーモノリス構成を敷いています。各モジュールごとに設定ファイルを置きたいことがあります。普通にやるとハマるんですが、割と簡単な方法で解決できるのでご紹介します。
前提
openjdk 17.0.5 2022-10-18 LTS OpenJDK Runtime Environment GraalVM 22.3.0 (build 17.0.5+8-LTS) OpenJDK 64-Bit Server VM GraalVM 22.3.0 (build 17.0.5+8-LTS, mixed mode, sharing)
- Gradle
------------------------------------------------------------ Gradle 7.6 ------------------------------------------------------------ Build time: 2022-11-25 13:35:10 UTC Revision: daece9dbc5b79370cc8e4fd6fe4b2cd400e150a8 Kotlin: 1.7.10 Groovy: 3.0.13 Ant: Apache Ant(TM) version 1.10.11 compiled on July 10 2021 JVM: 17.0.5 (BellSoft 17.0.5+8-LTS) OS: Mac OS X 12.5 aarch64
- SpringBoot
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.0.1)
ディレクトリツリー
マルチモジュール構成のディレクトリツリーはこのような感じです。
├── service │ └── src │ ├── main │ │ ├── java │ │ │ ├── com │ │ │ │ └── example │ │ │ └── jp │ │ │ └── co │ │ │ └── excite │ │ │ └── example │ │ │ └── Config.java │ │ └── resources │ │ └── application.yml └── web-front └── src ├── main │ ├── java │ │ └── jp │ │ └── co │ │ └── excite │ │ └── example │ │ ├── ExampleApplication.java │ │ └── controller │ │ └── RootController.java │ └── resources │ └── application.yml
web-frontとserviceアプリケーションがあります。起動アプリケーションは、web-frontになります。サービスに必要な主要な設定はweb-frontのapplication.yml
にあるんですが、service層固有の設定はservice層内のapplication.yml
に書きたいところです。
application.ymlは1度しか読まれない
SpringBootの仕様として、jarファイル内にあるapplication.yml
(or application.properties) が優先されるみたいです。SpringBootの外部の設定ファイルの仕様 つまり、同名の設定ファイルだと起動アプリケーションの application.yml
が優先されてしまうので、service層のapplication.yml
は別名にする必要があります。
マルチモジュール構成でのapplication.ymlの有効化
それでは、service層でも、固有の設定をapplication.ymlに書けるように変更していきます。
- application.ymlの名前変更
ファイル構成はこのようになります。変更点は、service層のapplication.yml
が、application-service.yml
になっています。
├── service │ └── src │ ├── main │ │ ├── java │ │ │ ├── com │ │ │ │ └── example │ │ │ └── jp │ │ │ └── co │ │ │ └── excite │ │ │ └── example │ │ │ └── Config.java │ │ └── resources │ │ └── application-service.yml └── web-front └── src ├── main │ ├── java │ │ └── jp │ │ └── co │ │ └── excite │ │ └── example │ │ ├── ExampleApplication.java │ │ └── controller │ │ └── RootController.java │ └── resources │ └── application.yml
ファイル名を変更することで、設定ファイル名の重複を回避します。
- 起動アプリケーションのapplication.ymlの修正
起動アプリケーションのapplication.ymlに下記を追加します。
spring: profiles: include: - service
これを追加することで、SpringBootは起動時にapplication-service.yml
を探しに言ってくれるようになります。
実行
では実行してみましょう。
application-service.yml
には下記のような設定を書いておきます。
service: id: 1234 name: service
読み出し用のJavaConfigは下記のように記述します。
@Component @ConfigurationProperties("service") @Data public class Config { private Integer id; private String name; }
参考までに、Rootコンロトーラは下記のように記述します。
@RestController @RequestMapping("/") @RequiredArgsConstructor public class RootController { private final Config config; @GetMapping public Object index(){ return config; } }
では、起動してリクエストしてみます。
$ ./gradlew web-front:bootRun $ curl http://localhost:8080/ {"id":1234,"name":"service"}
application-service.ymlに書いてある設定が読み出せています。
まとめ
これで、MultiModule構成でもModule固有のapplication.yml
が使えるようになりました。命名等に気をつける必要がある、起動アプリケーションの設定ファイルで指定する必要があるなど、いくつかポイントはありますが、無事に分離できました。
ただし、SpringBootのフレームワーク的には、application.yml
は1つであることが望ましい記述があるので、参考程度としてください。
最後に
エキサイトではフロントエンジニア、バックエンドエンジニア、アプリエンジニアを随時募集しております。長期インターンも歓迎していますので、興味があれば連絡いただければと思います。
カジュアル面談はこちらになります! meety.net
募集職種一覧はこちらになります!(カジュアルからもOK) www.wantedly.com