|
此版本仍在开发中,尚未被视为稳定版本。如需最新稳定版本,请使用 Spring Boot 4.0.4! |
开发者工具
Spring Boot 包含一组额外的工具,可让应用程序开发体验更加愉快。
spring-boot-devtools 模块可添加到任何项目中,以提供额外的开发时功能。
若要启用开发工具(devtools)支持,请将该模块依赖项添加到您的构建配置中,如下列 Maven 和 Gradle 配置示例所示:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
dependencies {
developmentOnly("org.springframework.boot:spring-boot-devtools")
}
| Devtools 可能导致类加载问题,尤其是在多模块项目中。 诊断类加载问题 介绍了如何诊断和解决此类问题。 |
当运行完全打包的应用程序时,开发人员工具会自动禁用。
如果您的应用程序是从 java -jar 启动的,或者通过特定的类加载器启动,则该应用被视为“生产环境应用”。
您可以通过使用 spring.devtools.restart.enabled 系统属性来控制此行为。
若要启用开发人员工具(无论启动应用程序所使用的类加载器为何),请设置 -Dspring.devtools.restart.enabled=true 系统属性。
在生产环境中不得执行此操作,因为在生产环境中运行开发人员工具存在安全风险。
若要禁用开发人员工具,可排除相关依赖项,或设置 -Dspring.devtools.restart.enabled=false 系统属性。 |
在 Maven 中将该依赖项标记为可选,或在 Gradle 中使用 developmentOnly 配置(如上所示),可防止开发工具(devtools)被传递性地应用于使用您项目的其他模块。 |
重新打包的归档文件默认不包含 DevTools。
如果您希望使用某项远程 DevTools 功能,则需要显式包含它。
在使用 Maven 插件时,请将 excludeDevtools 属性设置为 false。
在使用 Gradle 插件时,请配置任务的类路径以包含 developmentOnly 配置。 |
属性默认值
Spring Boot 支持的多个库使用缓存来提升性能。 例如,模板引擎 会缓存已编译的模板,以避免重复解析模板文件。 此外,Spring MVC 在提供静态资源时,可向响应中添加 HTTP 缓存头。
虽然缓存对生产环境非常有益,但在开发过程中却可能适得其反,导致您无法看到刚刚在应用程序中所做的更改。 因此,spring-boot-devtools 默认禁用了缓存选项。
缓存选项通常通过 application.properties 文件中的配置项进行设置。
例如,Thymeleaf 提供了 spring.thymeleaf.cache 属性。
无需手动设置这些属性,spring-boot-devtools 模块会自动应用合理的开发时配置。
以下表格列出了所有已应用的属性:
| 名称 | 默认值 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果您不希望应用属性默认值,可以在您的 application.properties 中将 spring.devtools.add-properties 设置为 false。 |
由于在开发 Spring MVC 和 Spring WebFlux 应用程序时,您需要获取更多有关 Web 请求的信息,因此开发工具建议您为 DEBUG 日志组启用 web 级别日志记录。
这将为您提供有关传入请求、处理该请求的处理器、响应结果以及其他详细信息。
如果您希望记录所有请求详情(包括潜在的敏感信息),可以启用 spring.mvc.log-request-details 或 spring.http.codecs.log-request-details 配置属性。
自动重启
使用 spring-boot-devtools 的应用程序会在类路径(classpath)中的文件发生更改时自动重启。
在集成开发环境(IDE)中进行开发时,此功能非常有用,因为它能为代码修改提供极快的反馈循环。
默认情况下,类路径中指向目录的任何条目都会被监控其变更。
请注意,某些资源(例如静态资源和视图模板)无需重启应用程序即可生效。
如果使用构建插件(Maven 或 Gradle)重新启动应用,则必须将 forking 保持为 enabled。
如果禁用分叉(forking),DevTools 所使用的隔离应用程序类加载器将不会被创建,从而导致重启功能无法正常工作。 |
| 自动重启功能与 LiveReload 配合使用时效果极佳。 详情请参阅 LiveReload 章节。 如果您使用 JRebel,则会禁用自动重启功能,转而采用动态类重载。 其他开发工具功能(例如 LiveReload 和属性覆盖)仍可正常使用。 |
DevTools 依赖应用程序上下文的关闭钩子(shutdown hook)在重启期间将其关闭。
如果您已禁用关闭钩子(SpringApplication.setRegisterShutdownHook(false)),则无法正常工作。 |
DevTools 需要自定义 ResourceLoader,该实例由 ApplicationContext 使用。
如果您的应用程序已提供该实例,则它将被包装。
不支持直接重写 ApplicationContext 上的 getResource 方法。 |
| 使用 AspectJ 织入时,不支持自动重启。 |
记录条件评估中的变更
默认情况下,每次应用程序重启时,都会记录一份显示条件评估差异的报告。 该报告展示了当您进行添加或删除 Bean、设置配置属性等更改时,应用程序自动配置所发生的变化。
要禁用报告的日志记录,请设置以下属性:
-
Properties
-
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,则应设置以下属性:
-
Properties
-
YAML
spring.devtools.restart.exclude=static/**,public/**
spring:
devtools:
restart:
exclude: "static/**,public/**"
如果您希望保留这些默认设置,同时添加其他排除项,请改用spring.devtools.restart.additional-exclude属性。 |
禁用重启
如果您不想使用重启功能,可以通过设置 spring.devtools.restart.enabled 属性来禁用它。
在大多数情况下,您可以在 application.properties 中设置该属性(这样做仍会初始化重启类加载器,但不会监听文件变更)。
如果需要完全禁用重启支持(例如,因为该功能与某个特定库不兼容),则必须在调用SpringApplication.run(…)之前将spring.devtools.restart.enabled System属性设置为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 会持续编译已更改的文件,你可能更倾向于仅在特定时间触发重启操作。 为此,你可以使用一个“触发文件”(trigger file),这是一种特殊文件,只有当你希望实际触发重启检查时才需要修改它。
| 对文件的任何更新都会触发检查,但仅当 Devtools 检测到该更新与其相关时,才会真正执行重启。 |
要使用触发器文件,请将 spring.devtools.restart.trigger-file 属性设置为触发器文件的名称(不包含任何路径)。
该触发器文件必须位于类路径(classpath)中的某个位置。
例如,如果你的项目具有以下结构:
src
+- main
+- resources
+- .reloadtrigger
那么您的 trigger-file 属性将为:
-
Properties
-
YAML
spring.devtools.restart.trigger-file=.reloadtrigger
spring:
devtools:
restart:
trigger-file: ".reloadtrigger"
重启操作现在仅在 src/main/resources/.reloadtrigger 被更新时发生。
您可能希望将 spring.devtools.restart.trigger-file 设为全局设置,以便所有项目均以相同方式运行。 |
某些集成开发环境(IDE)具备相应功能,可避免您手动更新触发文件。
Eclipse 的 Spring Tools 和 IntelliJ IDEA(旗舰版) 均支持此功能。
在 Spring Tools 中,您可使用控制台视图中的“重新加载”按钮(前提是您的 trigger-file 文件命名为 .reloadtrigger)。
对于 IntelliJ IDEA,您可以参考其文档中的 相关说明。
自定义重启类加载器
如前面重启与重载一节所述,重启功能是通过使用两个类加载器来实现的。
如果这导致了问题,您可以使用spring.devtools.restart.enabled系统属性来诊断该问题;如果关闭重启后应用程序可以正常运行,则您可能需要自定义由哪个类加载器加载哪些内容。
默认情况下,IDE 中任何已打开的项目均使用“restart”类加载器加载,而任何常规的 .jar 文件则使用“base”类加载器加载。
若使用 mvn spring-boot:run 或 gradle bootRun,情况同样如此:包含您的 @SpringBootApplication 的项目使用“restart”类加载器加载,其余所有内容则使用“base”类加载器加载。
应用启动时,类路径会打印在控制台中,这有助于识别任何存在问题的条目。
以反射方式使用的类(尤其是注解)可能在应用类(即使用这些类的类)加载之前,便已加载到父级(固定)类加载器中;这可能导致 Spring 在应用中无法检测到它们。
您可以通过创建一个 META-INF/spring-devtools.properties 文件,指示 Spring Boot 使用不同的类加载器来加载项目的部分组件。
该 spring-devtools.properties 文件可包含以 restart.exclude 和 restart.include 为前缀的属性。
include 元素表示应提升至“重启”类加载器中的项,而 exclude 元素表示应降级至“基础”类加载器中的项。
该属性的值是一个正则表达式模式,将在 JVM 启动时应用于传递给 JVM 的类路径。
以下示例中,某些本地类文件被排除在重启类加载器之外,而某些额外的库则被包含在重启类加载器中:
restart.exclude.companycommonlibs="/mycorp-common-[\\w\\d-\\.]/(build|bin|out|target)/"
restart.include.projectcommon="/mycorp-myproj-[\\w\\d-\\.]+\\.jar"
所有属性键必须唯一。
只要属性以 restart.include. 或 restart.exclude. 开头,即被视为有效。 |
从类路径加载所有 META-INF/spring-devtools.properties。
您可以将文件打包到项目内部,或打包到项目所依赖的库中。
无法使用系统属性,仅支持属性文件。 |
已知限制
重启功能与通过标准 ObjectInputStream 反序列化的对象配合使用时效果不佳。
如果需要反序列化数据,您可能需要将 Spring 的 ConfigurableObjectInputStream 与 Thread.currentThread().getContextClassLoader() 结合使用。
遗憾的是,一些第三方库在反序列化时并未考虑上下文类加载器(context classloader)。 如果遇到此类问题,您需要向原始作者请求修复。
实时重载
spring-boot-devtools 模块包含一个嵌入式的 LiveReload 服务器,当资源发生更改时,该服务器可触发浏览器刷新。
Chrome、Firefox 和 Safari 浏览器均提供免费的 LiveReload 浏览器扩展。
您可在所选浏览器的市场或应用商店中搜索“LiveReload”来找到这些扩展。
如果不想在应用程序运行时启动 LiveReload 服务器,可以将 spring.devtools.livereload.enabled 属性设置为 false。
| 一次只能运行一个 LiveReload 服务器。 启动应用程序之前,请确保没有其他 LiveReload 服务器正在运行。 如果您从集成开发环境(IDE)中启动多个应用程序,则只有第一个应用程序支持 LiveReload。 |
| 当文件发生更改时,要触发 LiveReload,必须启用自动重启功能。 |
全局设置
您可以通过向 $HOME/.config/spring-boot 目录中添加以下任一文件来配置全局 DevTools 设置:
-
spring-boot-devtools.properties -
spring-boot-devtools.yaml -
spring-boot-devtools.yml
添加到这些文件中的任何属性,均适用于您计算机上所有使用开发工具(devtools)的 Spring Boot 应用程序。
例如,若要配置重启功能始终使用触发文件,则需将以下属性添加到您的 spring-boot-devtools 文件中:
-
Properties
-
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 文件。
这样,您便可以与使用较旧版本 Spring Boot(不支持 $HOME/.config/spring-boot 位置)的应用程序共享 devtools 全局配置。 |
|
devtools 属性/YAML 文件不支持配置文件(Profiles)。 在 |
配置文件系统监视器
FileSystemWatcher 通过以特定时间间隔轮询类的变化,然后等待一段预定义的静默期,以确保不再有其他更改。
由于 Spring Boot 完全依赖 IDE 来编译并将文件复制到 Spring Boot 可读取的位置,因此您可能会发现,在开发工具(devtools)重启应用程序时,某些更改有时无法及时反映出来。
如果您持续遇到此类问题,请尝试将 spring.devtools.restart.poll-interval 和 spring.devtools.restart.quiet-period 参数调整为更符合您开发环境的值:
-
Properties
-
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 属性。
与任何重要的密码或密钥一样,该值应具有唯一性和强健性,以防止被猜测或暴力破解。
远程开发工具支持分为两部分:一个用于接收连接的服务器端端点,以及一个您在集成开发环境(IDE)中运行的客户端应用程序。
当设置 spring.devtools.remote.secret 属性时,服务器组件将自动启用。
客户端组件必须手动启动。
| 远程开发工具不支持 Spring WebFlux 应用程序。 |
运行远程客户端应用程序
远程客户端应用程序设计为在您的集成开发环境(IDE)中运行。
您需要使用与所连接的远程项目相同的类路径来运行 RemoteSpringApplication。
该应用程序唯一必需的参数是其要连接的远程 URL。
例如,如果您使用的是 Eclipse 或 Spring Tools,并且已将一个名为 my-app 的项目部署到 Cloud Foundry,则需执行以下操作:
-
从
Run菜单中选择Run Configurations…。 -
创建一个新的
Java Application“启动配置”。 -
浏览
my-app项目。 -
使用
RemoteSpringApplication作为主类。 -
将
https://myapp.cfapps.io添加到Program arguments(或您实际使用的远程 URL)。
正在运行的远程客户端可能类似于以下列表:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \
\\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) )
' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / /
=========|_|==============|___/===================================/_/_/_/
:: Spring Boot Remote :: (v3.5.13-SNAPSHOT)
2026-03-20T13:11:28.275Z INFO 90409 --- [ main] o.s.b.devtools.RemoteSpringApplication : Starting RemoteSpringApplication v3.5.13-SNAPSHOT using Java 17.0.18 with PID 90409 (/Users/myuser/.m2/repository/org/springframework/boot/spring-boot-devtools/3.5.13-SNAPSHOT/spring-boot-devtools-3.5.13-SNAPSHOT.jar started by myuser in /opt/apps/)
2026-03-20T13:11:28.278Z INFO 90409 --- [ main] o.s.b.devtools.RemoteSpringApplication : No active profile set, falling back to 1 default profile: "default"
2026-03-20T13:11:28.814Z INFO 90409 --- [ main] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2026-03-20T13:11:28.871Z INFO 90409 --- [ main] o.s.b.devtools.RemoteSpringApplication : Started RemoteSpringApplication in 1.851 seconds (process running for 2.531)
由于远程客户端与实际应用程序使用相同的类路径,因此可直接读取应用程序属性。
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 参数的值增大至适合您开发环境的数值。
有关如何配置这些属性,请参阅 配置文件系统监视器 一节。
| 仅当远程客户端正在运行时,才会监控文件。 如果在启动远程客户端之前更改了文件,则该文件不会被推送到远程服务器。 |