|
此版本仍在开发中,尚未视为稳定版。如需最新稳定版本,请使用 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)。
如果您想使用特定的远程开发工具功能,则需要将其包含在内。
使用 Maven 插件时,通过将 includeOptional 属性设置为 true 来选择性包含可选依赖项。
您还需要将 excludeDevtools 属性设置为 false。
使用 Gradle 插件时,配置任务的类路径以包含 developmentOnly 配置。 |
诊断类加载问题
如重启与重新加载的区别部分所述,重启功能是通过使用两个类加载器实现的。 对于大多数应用而言,这种方法工作得很好。 然而,在多模块项目中,有时可能会引起类加载问题。
要诊断类加载问题是否确实由 devtools 及其两个类加载器引起,请尝试禁用重启功能。 如果这解决了您的问题,请自定义重启类加载器以包含您的整个项目。
属性默认值
Spring Boot 所支持的多个库都使用缓存来提升性能。 例如,模板引擎会缓存已编译的模板,以避免重复解析模板文件。 此外,Spring MVC 在提供静态资源时,可以向响应中添加 HTTP 缓存头。
缓存虽然在生产环境中非常有益,但在开发过程中可能会适得其反,因为它会阻止你看到刚在应用中所做的更改。 因此,默认情况下,spring-boot-devtools 禁用了缓存选项。
缓存选项通常通过 application.properties 文件中的配置进行设置。
例如,Thymeleaf 提供了 spring.thymeleaf.cache 属性。
同样的情况也适用于追踪概率,因为默认设置为100%的追踪概率可能不会记录所有用于测试的追踪信息。
无需手动设置这些属性,spring-boot-devtools 模块会自动应用合理的开发时配置。
以下表格列出了所有应用的属性:
| 姓名 | 默认值 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果不希望属性默认值被应用,您可以在您的spring.devtools.add-properties中将false设置为application.properties。 |
因为您在开发 Spring MVC 和 Spring WebFlux 应用程序时需要更多关于 web 请求的信息,开发者工具建议您为 DEBUG 日志组启用 web 日志记录。
这将为您提供有关传入请求、正在处理该请求的处理器、响应结果以及其他详细信息。
如果您希望记录所有请求细节(包括可能敏感的信息),可以开启 spring.mvc.log-request-details 或 spring.http.codecs.log-request-details 配置属性。
自动重启
使用 spring-boot-devtools 的应用程序在类路径上的文件发生更改时会自动重启。
在 IDE 中开发时,这一功能非常有用,因为它能为代码更改提供极快的反馈循环。
默认情况下,类路径中指向目录的所有条目都会被监控以检测变化。
请注意,某些资源(例如静态资源和视图模板)无需重启应用程序。
如果使用 Maven 或 Gradle 的构建插件重新启动,必须将 forking 设置为 enabled。
如果不启用分叉,开发工具包使用的隔离应用类加载器将不会被创建,重启功能也将无法正常工作。 |
| 如果你使用 JRebel,自动重启将被禁用,转而使用动态类重载。 其他 devtools 功能(例如属性覆盖)仍然可以使用。 |
DevTools 依赖于应用程序上下文的退出钩子,在重启时关闭它。
如果已禁用退出钩子 (SpringApplication.setRegisterShutdownHook(false)),则不会正确工作。 |
DevTools 需要自定义由 ApplicationContext 使用的 ResourceLoader。
如果您的应用程序已经提供了一个,它将被包装。
不支持直接覆盖 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属性。 |
监视其他路径
当您修改了不在类路径(classpath)上的文件时,可能希望应用程序能够重启或重新加载。
为此,请使用 spring.devtools.restart.additional-paths 属性来配置需要监视变更的额外路径。
您可以使用前面描述过的 #using.devtools.restart.excluding-resources 属性,来控制在这些额外路径下的文件变更是否会触发完整重启,还是仅触发实时重载(live reload)。
禁用重启
如果您不需要使用重启功能,可以通过设置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,您可能更希望在特定时间触发重启。 要实现这一点,可以使用一个“触发文件”,该文件必须在需要实际触发重启检查时进行修改。
| 任何更新文件的操作都将触发检查,但实际重启仅在Devtools检测到有需要处理的内容时才会发生。 |
使用触发文件时,请将spring.devtools.restart.trigger-file属性设置为触发文件的名称(不包括路径)。
触发文件必须出现在您的类路径中的某个位置。
例如,如果你有一个具有以下结构的项目:
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 文件则使用
您可以使用 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)/"
restart.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 4.1.0 起已被弃用,且无替代方案。 |
The spring-boot-devtools 模块包含一个内嵌的 LiveReload 服务器,可以在资源更改时触发浏览器刷新。
LiveReload 浏览器扩展程序可以免费在 Chrome、Firefox 和 Safari 中获取。
您可以通过在所选浏览器的应用商店或市场中搜索 'LiveReload' 来找到这些扩展程序。
如果你想在应用程序运行时启动 LiveReload 服务器,可以将 spring.devtools.livereload.enabled 属性设置为 true。
| 您一次只能运行一个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 全局配置。 |
|
profiles 不支持在 devtools 属性/_yaml 文件 中。 在 |
配置文件系统监视器
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>
<includeOptional>true</includeOptional>
<excludeDevtools>false</excludeDevtools>
</configuration>
</plugin>
</plugins>
</build>
可选依赖项默认不会被包含,这也解释了为什么还存在 includeOptional。 |
然后您需要设置spring.devtools.remote.secret属性。
就像任何重要的密码或密钥一样,其值应是唯一且强大的,不能被猜测或暴力破解。
远程调试工具支持分为两部分:一个接受连接的服务器端端点和一个您在IDE中运行的客户端应用程序。
服务器组件会在设置spring.devtools.remote.secret属性时自动启用。
客户端组件需要手动启动。
| 远程调试工具不支持Spring WebFlux应用程序。 |
运行远程客户端应用程序
远程客户端应用程序设计为在您的 IDE 中运行。
您需要使用与所连接的远程项目相同的类路径运行 RemoteSpringApplication。
该应用程序唯一必需的参数是它要连接的远程 URL。
例如,如果您正在使用Eclipse或Spring Tools,并且有一个名为my-app的项目并且您已经将其部署到Cloud Foundry,则可以执行以下操作:
-
从
Run Configurations…菜单中选择Run。 -
创建一个新的
Java Application“启动配置”。 -
浏览
my-app项目。 -
使用
RemoteSpringApplication作为主类。 -
将
https://myapp.cfapps.io添加到Program arguments中(或根据您的远程URL进行相应设置)。
一个正在运行的远程客户端可能类似于以下列表:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \
\\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) )
' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / /
=========|_|==============|___/===================================/_/_/_/
:: Spring Boot Remote :: (v4.1.0-SNAPSHOT)
2026-03-20T13:14:34.030Z INFO 93144 --- [ main] o.s.b.devtools.RemoteSpringApplication : Starting RemoteSpringApplication v4.1.0-SNAPSHOT using Java 25.0.2 with PID 93144 (/Users/myuser/.m2/repository/org/springframework/boot/spring-boot-devtools/4.1.0-SNAPSHOT/spring-boot-devtools-4.1.0-SNAPSHOT.jar started by myuser in /opt/apps/)
2026-03-20T13:14:34.041Z INFO 93144 --- [ main] o.s.b.devtools.RemoteSpringApplication : No active profile set, falling back to 1 default profile: "default"
2026-03-20T13:14:34.935Z INFO 93144 --- [ main] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2026-03-20T13:14:35.016Z INFO 93144 --- [ main] o.s.b.devtools.RemoteSpringApplication : Started RemoteSpringApplication in 2.212 seconds (process running for 3.054)
因为远程客户端使用了与实际应用相同的类路径,所以可以直接读取应用属性。
这就是spring.devtools.remote.secret属性是如何被读取并传递给服务器进行身份验证的。 |
使用https://作为连接协议总是明智的,这样可以确保数据加密,防止密码被截获。 |
如果需要通过代理访问远程应用,请配置spring.devtools.remote.proxy.host和spring.devtools.remote.proxy.port属性。 |
远程更新
远程客户端以与本地重启相同的方式监控您的应用程序类路径中的更改。 任何更新的资源都会被推送到远程应用程序,并(如有需要)触发一次重启。 如果您正在开发一个依赖于本地没有的云服务的功能,这种方式会非常有帮助。 通常,远程更新和重启比完整的重新构建和部署周期要快得多。
在较慢的开发环境中,静默期可能不足以应对类的变化,导致类的变化被分批处理。<code>第一批次的类变化上传后会重启服务器。</code><br>由于服务器正在重启,<code>后续批次无法发送到应用程序</code>。
这通常表现为 RemoteSpringApplication 日志中出现关于上传部分类失败的警告,并随之进行重试。
但也可能导致应用程序代码不一致,以及在上传第一批更改后无法重新启动。
如果您经常观察到此类问题,请尝试将 spring.devtools.restart.poll-interval 和 spring.devtools.restart.quiet-period 参数增加到适合您开发环境的值。
请参阅 配置文件系统监视器 部分以配置这些属性。
| 文件仅在远程客户端运行时监控。<br>如果您在启动远程客户端之前更改了文件,则不会推送到远程服务器。 |