開発者ツール

Spring Boot には、アプリケーション開発エクスペリエンスをもう少し快適にすることができる追加のツールセットが含まれています。spring-boot-devtools モジュールを任意のプロジェクトに含めて、追加の開発時機能を提供できます。devtools サポートを含めるには、Maven および Gradle の次のように、ビルドにモジュール依存関係を追加します。

Maven
<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-devtools</artifactId>
		<optional>true</optional>
	</dependency>
</dependencies>
Gradle
dependencies {
	developmentOnly("org.springframework.boot:spring-boot-devtools")
}
Devtools は、特にマルチモジュールプロジェクトで、クラスローディングの課題を引き起こす可能性があります。クラスローディングの課題の診断は、診断して解決する方法を説明しています。
完全にパッケージ化されたアプリケーションを実行すると、開発者ツールは自動的に無効になります。アプリケーションが java -jar から起動された場合、または特別なクラスローダーから起動された場合、「本番アプリケーション」と見なされます。この動作は、spring.devtools.restart.enabled システムプロパティを使用して制御できます。アプリケーションの起動に使用されるクラスローダーに関係なく、devtools を有効にするには、-Dspring.devtools.restart.enabled=true システムプロパティを設定します。これは、devtools の実行がセキュリティリスクとなる本番環境では実行しないでください。devtools を無効にするには、依存関係を除外するか、-Dspring.devtools.restart.enabled=false システムプロパティを設定します。
Maven で依存関係にオプションのフラグを立てるか、Gradle で developmentOnly 構成を使用すると(上記のように)、プロジェクトを使用する他のモジュールに devtools が一時的に適用されなくなります。
再パッケージ化されたアーカイブには、デフォルトでは devtools が含まれません。特定のリモート devtools 機能を使用したい場合は、それを含める必要があります。Maven プラグインを使用する場合は、excludeDevtools プロパティを false に設定します。Gradle プラグインを使用する場合は、developmentOnly 構成を含むようにタスクのクラスパスを構成します

クラスローディングの課題の診断

再起動とリロードセクションに従って、再起動機能は 2 つのクラスローダーを使用して実装されます。ほとんどのアプリケーションでは、このアプローチが適切に機能します。ただし、特にマルチモジュールプロジェクトでは、クラスローディングの問題が発生する場合があります。

クラスローディングの課題が実際に devtools とその 2 つのクラスローダーによって引き起こされているかどうかを診断するには、restart を無効にしてみてください。これで課題が解決した場合は、プロジェクト全体が含まれるようにリスタートクラスローダーをカスタマイズします。

プロパティのデフォルト

Spring Boot がサポートするライブラリのいくつかは、キャッシュを使用してパフォーマンスを向上させます。例: テンプレートエンジンは、コンパイルされたテンプレートをキャッシュして、テンプレートファイルを繰り返し解析しないようにします。また、Spring MVC は、静的リソースを提供するときに、レスポンスに HTTP キャッシングヘッダーを追加できます。

キャッシュは本番環境では非常に有益ですが、開発中は逆効果になる可能性があり、アプリケーションで行った変更を確認できなくなります。このため、spring-boot-devtools はデフォルトでキャッシュオプションを無効にします。

キャッシュオプションは通常、application.properties ファイルの設定によって構成されます。例: Thymeleaf は spring.thymeleaf.cache プロパティを提供します。spring-boot-devtools モジュールは、これらのプロパティを手動で設定する必要があるのではなく、適切な開発時構成を自動的に適用します。

次の表に、適用されるすべてのプロパティを示します。

名前 デフォルト値

server.error.include-binding-errors

always

server.error.include-message

always

server.error.include-stacktrace

always

server.servlet.jsp.init-parameters.development

true

server.servlet.session.persistent

true

spring.docker.compose.readiness.wait

only-if-started

spring.freemarker.cache

false

spring.graphql.graphiql.enabled

true

spring.groovy.template.cache

false

spring.h2.console.enabled

true

spring.mustache.servlet.cache

false

spring.mvc.log-resolved-exception

true

spring.reactor.netty.shutdown-quiet-period

0s

spring.template.provider.cache

false

spring.thymeleaf.cache

false

spring.web.resources.cache.period

0

spring.web.resources.chain.cache

false

プロパティのデフォルトを適用したくない場合は、application.properties で spring.devtools.add-properties を false に設定できます。

Spring MVC および Spring WebFlux アプリケーションの開発中に Web リクエストに関する詳細情報が必要になるため、開発者ツールでは、web ロギンググループに対して DEBUG ロギングを有効にすることをお勧めします。これにより、受信リクエスト、それを処理しているハンドラー、レスポンス結果、その他の詳細に関する情報が得られます。すべてのリクエストの詳細(機密情報を含む)をログに記録する場合は、spring.mvc.log-request-details または spring.codec.log-request-details 構成プロパティをオンにすることができます。

自動再起動

spring-boot-devtools を使用するアプリケーションは、クラスパス上のファイルが変更されるたびに自動的に再起動します。これは IDE で作業するときに便利な機能です。コードの変更に対して非常に高速なフィードバックループを提供するためです。デフォルトでは、ディレクトリを指すクラスパスのエントリはすべて変更が監視されます。静的アセットやビューテンプレートなどの特定のリソースは、アプリケーションを再起動する必要がないことに注意してください。

再起動のトリガー

DevTools はクラスパスリソースを監視するため、再起動をトリガーする唯一の方法は、クラスパスを更新することです。IDE を使用している場合でも、ビルドプラグインのいずれかを使用している場合でも、再起動をトリガーするには、変更したファイルを再コンパイルする必要があります。クラスパスを更新する方法は、使用しているツールによって異なります。

  • Eclipse では、変更されたファイルを保存すると、クラスパスが更新され、再起動がトリガーされます。

  • IntelliJ IDEA では、プロジェクト(Build -> Build Project)をビルドしても同じ効果があります。

  • ビルドプラグインを使用している場合、Maven の場合は mvn compile を実行するか、Gradle の場合は gradle build を実行すると再起動がトリガーされます。

ビルドプラグインを使用して Maven または Gradle で再起動する場合は、forking を enabled に設定したままにする必要があります。フォークを無効にすると、devtools によって使用される分離されたアプリケーションクラスローダーが作成されず、再起動が正しく動作しません。
自動再起動は、LiveReload と併用すると非常にうまく機能します。詳細については、LiveReload セクションを参照してください。JRebel を使用する場合、動的なクラスの再読み込みを優先して自動再起動が無効になります。その他の devtools 機能(LiveReload やプロパティのオーバーライドなど)は引き続き使用できます。
DevTools は、アプリケーションコンテキストのシャットダウンフックに依存して、再起動中に閉じます。シャットダウンフック(SpringApplication.setRegisterShutdownHook(false))を無効にした場合、正しく機能しません。
DevTools は、ApplicationContext が使用する ResourceLoader をカスタマイズする必要があります。アプリケーションがすでに提供している場合、ラップされます。ApplicationContext での getResource メソッドの直接オーバーライドはサポートされていません。
AspectJ ウィービングを使用している場合、自動再起動はサポートされていません。
再起動とリロード

Spring Boot が提供する再起動テクノロジは、2 つのクラスローダーを使用して機能します。変更されないクラス(たとえば、サードパーティの jar からのクラス)は、基本クラスローダーにロードされます。積極的に開発しているクラスは、再起動クラスローダーにロードされます。アプリケーションを再起動すると、再起動クラスローダーが破棄され、新しいクラスローダーが作成されます。このアプローチは、基本クラスローダーがすでに利用可能であり、データが設定されているため、通常、アプリケーションの再起動は「コールドスタート」よりもはるかに高速であることを意味します。

アプリケーションの再起動が十分に速くない場合、またはクラスローディングの問題が発生した場合は、ZeroTurnaround の JRebel (英語) などのテクノロジを再ロードすることを検討できます。これらは、ロードされたときにクラスを書き換えて、再ロードしやすくすることで機能します。

条件評価における変更のロギング

デフォルトでは、アプリケーションを再起動するたびに、状態評価デルタを示すレポートが記録されます。このレポートには、Bean の追加や削除、構成プロパティの設定などの変更を行うと、アプリケーションの自動構成に対する変更が表示されます。

レポートのログを無効にするには、次のプロパティを設定します。

  • プロパティ

  • YAML

spring.devtools.restart.log-condition-evaluation-delta=false
spring:
  devtools:
    restart:
      log-condition-evaluation-delta: false

リソースを除外する

特定のリソースは、変更されたときに必ずしも再起動をトリガーする必要はありません。例: Thymeleaf テンプレートはその場で編集できます。デフォルトでは、/META-INF/maven/META-INF/resources/resources/static/public または /templates のリソースを変更しても再起動はトリガーされませんが、ライブリロードはトリガーされます。これらの除外をカスタマイズする場合は、spring.devtools.restart.exclude プロパティを使用できます。例: /static と /public のみを除外するには、次のプロパティを設定します。

  • プロパティ

  • YAML

spring.devtools.restart.exclude=static/**,public/**
spring:
  devtools:
    restart:
      exclude: "static/**,public/**"
これらのデフォルトを維持して除外を追加する場合は、代わりに spring.devtools.restart.additional-exclude プロパティを使用します。

追加パスの監視

クラスパスにないファイルに変更を加えた場合、アプリケーションを再起動または再ロードすることができます。これを行うには、spring.devtools.restart.additional-paths プロパティを使用して、変更を監視する追加のパスを構成します。前述の spring.devtools.restart.exclude プロパティを使用して、追加のパスにある変更が完全な再起動またはライブリロードをトリガーするかどうかを制御できます。

再起動を無効にする

再起動機能を使用しない場合は、spring.devtools.restart.enabled プロパティを使用して無効にすることができます。ほとんどの場合、application.properties でこのプロパティを設定できます(そうすると、再起動クラスローダーが初期化されますが、ファイルの変更は監視されません)。

再起動サポートを完全に無効にする必要がある場合(たとえば、特定のライブラリでは機能しないため)、次の例に示すように、SpringApplication.run(…​) を呼び出す前に spring.devtools.restart.enabledSystem プロパティを false に設定する必要があります。

  • Java

  • Kotlin

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication {

	public static void main(String[] args) {
		System.setProperty("spring.devtools.restart.enabled", "false");
		SpringApplication.run(MyApplication.class, args);
	}

}
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication

@SpringBootApplication
object MyApplication {

	@JvmStatic
	fun main(args: Array<String>) {
		System.setProperty("spring.devtools.restart.enabled", "false")
		SpringApplication.run(MyApplication::class.java, *args)
	}

}

トリガーファイルの使用

変更されたファイルを継続的にコンパイルする IDE を使用している場合、特定の時間にのみ再起動をトリガーすることをお勧めします。そのためには、「トリガーファイル」を使用できます。これは、実際に再起動チェックをトリガーするときに変更する必要がある特別なファイルです。

ファイルを更新すると、チェックがトリガーされますが、再起動は、Devtools が何らかの処理を行うことを検出した場合にのみ実際に発生します。

トリガーファイルを使用するには、spring.devtools.restart.trigger-file プロパティをトリガーファイルの名前(パスを除く)に設定します。トリガーファイルは、クラスパスのどこかに表示する必要があります。

例: 次の構造のプロジェクトがある場合:

src
+- main
   +- resources
      +- .reloadtrigger

trigger-file プロパティは次のようになります。

  • プロパティ

  • YAML

spring.devtools.restart.trigger-file=.reloadtrigger
spring:
  devtools:
    restart:
      trigger-file: ".reloadtrigger"

再起動は、src/main/resources/.reloadtrigger が更新されたときにのみ発生します。

すべてのプロジェクトが同じように動作するように、spring.devtools.restart.trigger-file をグローバル設定として設定できます。

一部の IDE には、トリガーファイルの手動更新を不要にする機能があります。Pleiades All in One (JDK, STS, Lombok 付属) または Eclipse 用 Spring Tools (英語) IntelliJ IDEA (Ultimate エディション) (英語) は両方ともそのようなサポートを持っています。Spring Tools では、コンソールビューから「リロード」ボタンを使用できます(trigger-file の名前が .reloadtrigger である限り)。IntelliJ IDEA については、このドキュメントの指示 (英語) に従ってください。

再起動クラスローダーのカスタマイズ

前述の再起動とリロードセクションで説明したように、再起動機能は 2 つのクラスローダーを使用して実装されます。これにより問題が発生する場合は、spring.devtools.restart.enabled システムプロパティを使用して課題を診断できます。また、再起動をオフにした状態でアプリが動作する場合は、どのクラスローダーによって何がロードされるかをカスタマイズする必要がある可能性があります。

デフォルトでは、IDE で開いているプロジェクトはすべて「再起動」クラスローダーでロードされ、通常の .jar ファイルはすべて「ベース」クラスローダーでロードされます。mvn spring-boot:run または gradle bootRun を使用する場合も同様です。@SpringBootApplication を含むプロジェクトは「再起動」クラスローダーでロードされ、その他すべては「ベース」クラスローダーでロードされます。クラスパスはアプリを起動するとコンソールに表示されるため、問題のあるエントリを特定できます。リフレクションによって使用されるクラス、特にアノテーションは、起動時に使用するアプリケーションクラスよりも先に親 (固定) クラスローダーにロードされる可能性があり、これによりアプリケーションで Spring によって検出されない可能性があります。

META-INF/spring-devtools.properties ファイルを作成することで、Spring Boot にプロジェクトの一部を別のクラスローダーでロードするように指示できます。spring-devtools.properties ファイルには、restart.exclude および restart.include というプレフィックスが付いたプロパティを含めることができます。include 要素は「再起動」クラスローダーにプルアップされる項目であり、exclude 要素は「ベース」クラスローダーにプッシュダウンされる項目です。プロパティの値は、起動時に JVM に渡されるクラスパスに適用される正規表現パターンです。次の例では、一部のローカルクラスファイルが除外され、一部の追加ライブラリが再起動クラスローダーに含まれています。

restart:
  exclude:
    companycommonlibs: "/mycorp-common-[\\w\\d-\\.]/(build|bin|out|target)/"
  include:
    projectcommon: "/mycorp-myproj-[\\w\\d-\\.]+\\.jar"
すべてのプロパティキーは一意である必要があります。プロパティが restart.include. または restart.exclude. で始まる限り、考慮されます。
クラスパスからのすべての META-INF/spring-devtools.properties がロードされます。プロジェクト内、またはプロジェクトが使用するライブラリ内にファイルをパッケージ化できます。システムプロパティは使用できません。プロパティファイルのみ使用できます。

既知の制限

再起動機能は、標準の ObjectInputStream を使用してデシリアライズされたオブジェクトではうまく機能しません。データをデシリアライズする必要がある場合は、Spring の ConfigurableObjectInputStream を Thread.currentThread().getContextClassLoader() と組み合わせて使用する必要がある場合があります。

残念ながら、いくつかのサードパーティライブラリは、コンテキストクラスローダーを考慮せずにデシリアライズします。このような問題を見つけた場合は、元の作者に修正を依頼する必要があります。

LiveReload

spring-boot-devtools モジュールには、リソースが変更されたときにブラウザーのリフレッシュをトリガーするために使用できる組み込み LiveReload サーバーが含まれています。LiveReload ブラウザー拡張機能は、Chrome、Firefox、Safari でフリーで利用できます。これらの拡張機能は、選択したブラウザーのマーケットプレイスまたはストアで "LiveReload" を検索すると見つかります。

アプリケーションの実行時に LiveReload サーバーを開始したくない場合は、spring.devtools.livereload.enabled プロパティを false に設定できます。

一度に実行できる LiveReload サーバーは 1 つだけです。アプリケーションを開始する前に、他の LiveReload サーバーが実行されていないことを確認してください。IDE から複数のアプリケーションを起動する場合、最初のアプリケーションのみが LiveReload をサポートしています。
ファイルが変更されたときに LiveReload をトリガーするには、自動再起動を有効にする必要があります。

グローバル設定

以下のファイルのいずれかを $HOME/.config/spring-boot ディレクトリに追加することにより、グローバル devtools 設定を構成できます。

  1. spring-boot-devtools.properties

  2. spring-boot-devtools.yaml

  3. spring-boot-devtools.yml

これらのファイルに追加されたプロパティはすべて、 devtools を使用するマシン上のすべての Spring Boot アプリケーションに適用されます。例: 常にトリガーファイルを使用するように再起動を構成するには、spring-boot-devtools ファイルに次のプロパティを追加します。

  • プロパティ

  • YAML

spring.devtools.restart.trigger-file=.reloadtrigger
spring:
  devtools:
    restart:
      trigger-file: ".reloadtrigger"

デフォルトでは、$HOME はユーザーのホームディレクトリです。この場所をカスタマイズするには、SPRING_DEVTOOLS_HOME 環境変数または spring.devtools.home システムプロパティを設定します。

$HOME/.config/spring-boot に devtools 構成ファイルが見つからない場合、$HOME ディレクトリのルートで .spring-boot-devtools.properties ファイルの存在が検索されます。これにより、$HOME/.config/spring-boot の場所をサポートしない古いバージョンの Spring Boot にあるアプリケーションと devtools グローバル構成を共有できます。

プロファイルは、devtools プロパティ / yaml ファイルではサポートされていません。

.spring-boot-devtools.properties でアクティブ化されたプロファイルは、プロファイル固有の構成ファイルのロードには影響しません。YAML ファイルとプロパティファイルの両方で、プロファイル固有のファイル名 ( spring-boot-devtools-<profile>.properties 形式) と spring.config.activate.on-profile ドキュメントはサポートされていません。

File System Watcher の構成

FileSystemWatcher (Javadoc) は、一定の時間間隔でクラスの変更をポーリングし、その後、定義済みの待機期間を待って、それ以上の変更がないことを確認します。Spring Boot は、ファイルをコンパイルして Spring Boot が読み取れる場所にコピーするのに IDE に完全に依存しているため、devtools がアプリケーションを再起動したときに特定の変更が反映されない場合があります。このような問題が頻繁に発生する場合は、spring.devtools.restart.poll-interval および spring.devtools.restart.quiet-period パラメーターを開発環境に適した値に増やしてみてください。

  • プロパティ

  • YAML

spring.devtools.restart.poll-interval=2s
spring.devtools.restart.quiet-period=1s
spring:
  devtools:
    restart:
      poll-interval: "2s"
      quiet-period: "1s"

監視対象のクラスパスディレクトリが 2 秒ごとにポーリングされて変更が確認され、追加のクラス変更がないことを確認するために 1 秒の待機期間が維持されます。

リモートアプリケーション

Spring Boot 開発者ツールは、ローカル開発に限定されません。アプリケーションをリモートで実行するときに、いくつかの機能を使用することもできます。リモートサポートはオプトインです。これを有効にするとセキュリティ上のリスクになる可能性があります。信頼できるネットワークで実行している場合、または SSL で保護されている場合にのみ有効にしてください。これらのオプションのいずれも使用できない場合は、DevTools ' リモートサポートを使用しないでください。本番デプロイでサポートを有効にしないでください。

有効にするには、次のように、devtools が再パッケージ化されたアーカイブに含まれていることを確認する必要があります。

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
			<configuration>
				<excludeDevtools>false</excludeDevtools>
			</configuration>
		</plugin>
	</plugins>
</build>

次に、spring.devtools.remote.secret プロパティを設定する必要があります。重要なパスワードやシークレットと同様に、値は一意で強力で、推測や総当たり攻撃ができないようにする必要があります。

リモート devtools サポートは 2 つの部分で提供されます。接続を受け入れるサーバー側エンドポイントと、IDE で実行するクライアントアプリケーションです。spring.devtools.remote.secret プロパティが設定されると、サーバーコンポーネントは自動的に有効になります。クライアントコンポーネントは手動で起動する必要があります。

リモート devtools は、Spring WebFlux アプリケーションではサポートされていません。

リモートクライアントアプリケーションの実行

リモートクライアントアプリケーションは、IDE 内から実行されるように設計されています。接続するリモートプロジェクトと同じクラスパスで org.springframework.boot.devtools.RemoteSpringApplication を実行する必要があります。アプリケーションの単一の必須引数は、接続先のリモート URL です。

例: Eclipse または Spring Tools を使用していて、Cloud Foundry にデプロイした my-app という名前のプロジェクトがある場合は、次のようにします。

  • Run メニューから Run Configurations…​ を選択します。

  • 新しい Java Application 「起動構成」を作成します。

  • my-app プロジェクトを参照します。

  • org.springframework.boot.devtools.RemoteSpringApplication をメインクラスとして使用します。

  • https://myapp.cfapps.io を Program arguments (またはリモートの URL)に追加します。

実行中のリモートクライアントは、次のようになります。

  .   ____          _                                              __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _          ___               _      \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` |        | _ \___ _ __  ___| |_ ___ \ \ \ \
 \\/  ___)| |_)| | | | | || (_| []::::::[]   / -_) '  \/ _ \  _/ -_) ) ) ) )
  '  |____| .__|_| |_|_| |_\__, |        |_|_\___|_|_|_\___/\__\___|/ / / /
 =========|_|==============|___/===================================/_/_/_/
 :: Spring Boot Remote ::  (v3.3.1)

2024-06-20T10:08:21.082Z  INFO 111990 --- [           main] o.s.b.devtools.RemoteSpringApplication   : Starting RemoteSpringApplication v3.3.1 using Java 17.0.11 with PID 111990 (/Users/myuser/.m2/repository/org/springframework/boot/spring-boot-devtools/3.3.1/spring-boot-devtools-3.3.1.jar started by myuser in /opt/apps/)
2024-06-20T10:08:21.102Z  INFO 111990 --- [           main] o.s.b.devtools.RemoteSpringApplication   : No active profile set, falling back to 1 default profile: "default"
2024-06-20T10:08:22.021Z  INFO 111990 --- [           main] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2024-06-20T10:08:22.143Z  INFO 111990 --- [           main] o.s.b.devtools.RemoteSpringApplication   : Started RemoteSpringApplication in 2.346 seconds (process running for 4.394)
リモートクライアントは実際のアプリケーションと同じクラスパスを使用しているため、アプリケーションプロパティを直接読み取ることができます。これにより、spring.devtools.remote.secret プロパティが読み取られ、認証のためにサーバーに渡されます。
接続プロトコルとして https:// を使用することを常にお勧めします。これにより、トラフィックが暗号化され、パスワードをインターセプトできなくなります。
プロキシを使用してリモートアプリケーションにアクセスする必要がある場合は、spring.devtools.remote.proxy.host および spring.devtools.remote.proxy.port プロパティを構成します。

リモートアップデート

リモートクライアントは、ローカル再起動と同じ方法でアプリケーションクラスパスの変更を監視します。更新されたリソースはすべてリモートアプリケーションにプッシュされ、(必要な場合)再起動をトリガーします。これは、ローカルにないクラウドサービスを使用する機能を反復する場合に役立ちます。一般的に、リモートの更新と再起動は、完全な再構築とデプロイのサイクルよりもはるかに高速です。

遅い開発環境では、沈黙期間が十分ではなく、クラスの変更がバッチに分割される場合があります。クラス変更の最初のバッチがアップロードされた後、サーバーが再起動されます。サーバーが再起動しているため、次のバッチをアプリケーションに送信できません。

これは通常、一部のクラスのアップロードの失敗に関する RemoteSpringApplication ログの警告と、その結果の再試行によって明示されます。ただし、変更の最初のバッチがアップロードされた後、アプリケーションコードの不整合や再起動の失敗につながる可能性もあります。このような問題が常に発生する場合は、spring.devtools.restart.poll-interval および spring.devtools.restart.quiet-period パラメーターを開発環境に適した値に増やしてみてください。これらのプロパティの設定については、File System Watcher の構成セクションを参照してください。

ファイルは、リモートクライアントが実行されている場合にのみ監視されます。リモートクライアントを開始する前にファイルを変更した場合、そのファイルはリモートサーバーにプッシュされません。