Spring Boot 1.2.x の Web アプリを 1.3.x へバージョンアップする ( その7 )( devtools を入れて java -jar で起動しても spring.thymeleaf.cache = false になる原因を調査する )
概要
Spring Boot 1.2.x の Web アプリを 1.3.x へバージョンアップする ( その6 )( JRebel と devtools をどちらも入れた時の動作を確認する ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- devtools を入れて java -jar で起動しても spring.thymeleaf.cache = false になる原因を調査する
参照したサイト・書籍
64. Spring Boot Gradle plugin
http://docs.spring.io/spring-boot/docs/current/reference/html/build-tool-plugins-gradle-plugin.htmlSpring Boot Devtools by Example
http://stackoverflow.com/questions/37397038/spring-boot-devtools-by-example
目次
- devtools を入れると spring.thymeleaf.cache = false になる仕組みとは?
- devtools が入っていても spring.thymeleaf.cache = false にならないようにするにはどうすればよいのか?
- RemoteSpringApplication クラスとは?
- java -jar で起動した時に spring.thymeleaf.cache = false にならないようにするには結局どうする?
- 次回は。。。
手順
devtools を入れると spring.thymeleaf.cache = false になる仕組みとは?
spring-boot/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java の postProcessEnvironment メソッドでセットされています。ただし無条件でセットされているのではなく、引数 environment の getPropertySources() メソッドが返す PropertySource リストの中に "remoteUrl" という名称のものがなければセットしているようです。
environment.getPropertySources() が返す PropertySource リストを Debug モードで実行して確認したところ、以下の画像の結果でした。確かに "remoteUrl" のものはありませんでした。
devtools が入っていても spring.thymeleaf.cache = false にならないようにするにはどうすればよいのか?
environment.getPropertySources() が返す PropertySource リストの中に "remoteUrl" という名称のものがあればセットされるので、どうやればセットされるのかを調査します。
Spring Boot の GitHub の画面右上の Search フィールドに "remoteUrl" を入力して検索してみます。
ヒットしたのは以下の5つのファイルでした。
- spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/RemoteClientConfiguration.java
- spring-boot-devtools/src/main/java/org/springframework/boot/devtools/RemoteUrlPropertyExtractor.java
- spring-boot-devtools/src/test/java/org/springframework/boot/devtools/RemoteUrlPropertyExtractorTests.java
- spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java
- spring-boot-devtools/src/test/java/org/springframework/boot/devtools/remote/client/RemoteClientConfigurationTests.java
ざっと見てみると spring-boot-devtools/src/main/java/org/springframework/boot/devtools/RemoteUrlPropertyExtractor.java の onApplicationEvent メソッドで "remoteUrl" PropertySource をセットしているようです。
RemoteUrlPropertyExtractor#onApplicationEvent メソッドでは、nonOptionArgs プロパティにセットされている URL をセットした "remoteUrl" PropertySource を生成して environment にセットしています。
RemoteUrlPropertyExtractor クラスがどこで呼び出されているか調べてみます。GitHub の画面右上の Search フィールドに "RemoteUrlPropertyExtractor" を入力して検索します。
ヒットしたのは以下の3つのファイルでした。
- spring-boot-devtools/src/test/java/org/springframework/boot/devtools/RemoteUrlPropertyExtractorTests.java
- spring-boot-devtools/src/main/java/org/springframework/boot/devtools/RemoteUrlPropertyExtractor.java
- spring-boot-devtools/src/main/java/org/springframework/boot/devtools/RemoteSpringApplication.java
spring-boot-devtools/src/main/java/org/springframework/boot/devtools/RemoteSpringApplication.java の getListeners メソッドで listeners.add(new RemoteUrlPropertyExtractor());
と呼んでいますね。
RemoteSpringApplication クラスを見た感じでは RemoteSpringApplication#main メソッドが呼び出されればRemoteSpringApplication#run メソッドが呼び出されて、その中で getListeners メソッドが呼び出されます。
結局、devtools が入っていても spring.thymeleaf.cache = false にならないようにするためには以下のように ksbysample.webapp.lending.Application#main メソッドを呼び出さずに RemoteSpringApplication#main メソッドを呼び出して起動する、という方法のようです。
- DevToolsPropertyDefaultsPostProcessor#postProcessEnvironment で environment.getPropertySources() が返す PropertySource リストの中に "remoteUrl" という名称のものがあれば spring.thymeleaf.cache = false にはならない。
↓ - nonOptionArgs プロパティに URL がセットされた状態で RemoteUrlPropertyExtractor#onApplicationEvent が呼び出されれば environment.getPropertySources() が返す PropertySource リストの中に "remoteUrl" という名称のものが作成される。
↓ - RemoteSpringApplication#main が呼び出されれば、そこから呼び出される RemoteSpringApplication#run の中で RemoteUrlPropertyExtractor クラスのインスタンスが生成されて Listener としてセットされ、RemoteUrlPropertyExtractor#onApplicationEvent が呼び出されるようになる。
RemoteSpringApplication クラスとは?
RemoteSpringApplication クラスがそもそも何のためのクラスなのかが分からなかったので調査します。
Spring Boot Reference Guide の以下の章に RemoteSpringApplication クラスの記述がありました。読んだ感じでは URL を指定して Remote の Spring Application に接続するためのクラスのようです。
- Spring Boot Reference Guide - 20. Developer tools - 20.5.1 Running the remote client application
http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html#_running_the_remote_client_application
でも別に Remote の Spring Application に接続したい訳ではないので、RemoteSpringApplication#main を呼び出すのは何か求めているものと違う気がします。
java -jar で起動した時に spring.thymeleaf.cache = false にならないようにするには結局どうする?
java -jar で起動すると devtools が無効になるようには全く見えません。20. Developer tools をもう1度見てみると "Developer tools are automatically disabled when running a fully packaged application. " と書かれているのですが、"when running a fully packaged application." というのが単に jar ファイル作るのとどう違うのかも全然分かりません。
ちょっと今回は降参です。。。
何か他に方法がないかいろいろ探してみたところ、64. Spring Boot Gradle plugin に jar ファイルを作成する時に devtools.jar を入れないようにするための excludeDevtools オプションなるものがあると書かれているのを見つけました。これを設定して jar ファイルには devtools が入らないようにしてみたいと思います。
次回は。。。
excludeDevtools オプションを指定して jar ファイルには devtools を入れないようにした場合の動作確認をします。
ソースコード
履歴
2016/05/31
初版発行。