开发者工具
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 系统属性来控制此行为。要启用 devtools,无论用于启动应用程序的类加载器如何,请设置 -Dspring.devtools.restart.enabled=true 系统属性。这不能在生产环境中完成,因为运行 devtools 存在安全风险。要禁用 devtools,请排除依赖项或设置 -Dspring.devtools.restart.enabled=false 系统属性。 |
在 Maven 中将依赖项标记为可选,或在 Gradle 中使用 developmentOnly 配置(如上所示),可以防止 devtools 传递性地应用于使用您项目的其他模块。 |
默认情况下,重新打包的存档不包含 devtools。如果您想使用某个远程 devtools 功能,则需要将其包含在内。使用 Maven 插件时,请将 excludeDevtools 属性设置为 false。使用 Gradle 插件时,配置任务的 classpath 以包含 developmentOnly 配置。 |
属性默认值
Spring Boot 支持的几个库使用缓存来提高性能。例如,模板引擎 缓存编译的模板,以避免重复解析模板文件。此外,Spring MVC 在提供静态资源时可以向响应添加 HTTP 缓存头。
虽然缓存对生产环境非常有利,但在开发过程中可能会适得其反,阻止您看到刚在应用程序中所做的更改。因此,spring-boot-devtools 默认禁用缓存选项。
缓存选项通常通过 application.properties 文件中的设置进行配置。例如,Thymeleaf 提供 spring.thymeleaf.cache 属性。
对于跟踪概率也一样,默认设置为 100% 可能不会记录用于测试的所有跟踪。
无需手动设置这些属性,spring-boot-devtools 模块会自动应用合理的开发时配置。
下表列出了所有应用的属性
| 名称 | 默认值 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果您不希望应用属性默认值,可以在 application.properties 中将 spring.devtools.add-properties 设置为 false。 |
由于您在开发 Spring MVC 和 Spring WebFlux 应用程序时需要更多关于 Web 请求的信息,开发人员工具建议您为 web 日志组启用 DEBUG 级别日志记录。这将为您提供关于传入请求、处理请求的处理程序、响应结果和其他详细信息。如果您希望记录所有请求详细信息(包括可能敏感的信息),可以打开 spring.mvc.log-request-details 或 spring.http.codecs.log-request-details 配置属性。
自动重启
使用 spring-boot-devtools 的应用程序会在 classpath 中的文件更改时自动重启。这在 IDE 中工作时是一个有用的功能,因为它为代码更改提供了非常快速的反馈循环。默认情况下,classpath 中指向目录的任何条目都会被监控以检测更改。请注意,某些资源(例如静态资产和视图模板)不需要重启应用程序。
如果您使用构建插件通过 Maven 或 Gradle 进行重启,则必须将 forking 设置为 enabled。如果禁用 forking,devtools 使用的独立应用程序类加载器将不会创建,并且重启将无法正常运行。 |
| 自动重启与 LiveReload 结合使用效果非常好。有关详细信息,请参阅LiveReload 部分。如果您使用 JRebel,自动重启会被禁用,转而使用动态类重新加载。其他 devtools 功能(如 LiveReload 和属性覆盖)仍可使用。 |
DevTools 依赖于应用程序上下文的关闭钩子在重启期间关闭它。如果您禁用了关闭钩子(SpringApplication.setRegisterShutdownHook(false)),它将无法正常工作。 |
DevTools 需要自定义 ResourceLoader,该 ResourceLoader 由 ApplicationContext 使用。如果您的应用程序已经提供了一个,它将被包装。不支持直接覆盖 ApplicationContext 上的 getResource 方法。 |
| 使用 AspectJ 织入时不支持自动重启。 |
记录条件评估的变化
默认情况下,每次应用程序重启时,都会记录一个显示条件评估增量的报告。该报告显示了您在添加或删除 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.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 属性设置为触发文件的名称(不包括任何路径)。触发文件必须出现在您的 classpath 中的某个位置。
例如,如果您的项目结构如下
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 具有功能,可以省去您手动更新触发文件的麻烦。适用于 Eclipse 的 Spring Tools 和 IntelliJ IDEA (Ultimate Edition) 都支持此功能。使用 Spring Tools,您可以使用控制台视图中的“重新加载”按钮(只要您的 trigger-file 被命名为 .reloadtrigger)。对于 IntelliJ IDEA,您可以按照其文档中的说明进行操作。
自定义重启类加载器
如重启与重新加载部分所述,重启功能是通过使用两个类加载器来实现的。如果这导致问题,您可以使用 spring.devtools.restart.enabled 系统属性来诊断问题,如果应用程序在关闭重启后正常工作,您可能需要自定义哪些内容由哪个类加载器加载。
默认情况下,IDE 中的任何打开项目都使用“重启”类加载器加载,而任何常规 .jar 文件都使用“基本”类加载器加载。如果您使用 mvn spring-boot:run 或 gradle bootRun 也是如此:包含您的 @SpringBootApplication 的项目使用“重启”类加载器加载,其他所有内容都使用“基本”类加载器加载。应用程序启动时会在控制台打印 classpath,这有助于识别任何有问题的地方。反射使用的类,特别是注解,在应用程序使用它们之前可能被加载到父(固定)类加载器中,这可能导致它们未被 Spring 在应用程序中检测到。
您可以通过创建 META-INF/spring-devtools.properties 文件来指示 Spring Boot 使用不同的类加载器加载项目的一部分。spring-devtools.properties 文件可以包含以 restart.exclude 和 restart.include 为前缀的属性。include 元素是应被拉入“重启”类加载器的项,exclude 元素是应被推入“基本”类加载器的项。属性的值是一个正则表达式模式,应用于启动时传递给 JVM 的 classpath。这是一个示例,其中一些本地类文件被排除,一些额外的库被包含在重启类加载器中
restart:
exclude:
companycommonlibs: "/mycorp-common-[\\w\\d-\\.]/(build|bin|out|target)/"
include:
projectcommon: "/mycorp-myproj-[\\w\\d-\\.]+\\.jar"
所有属性键必须唯一。只要属性以 restart.include. 或 restart.exclude. 开头,它就会被考虑在内。 |
所有 classpath 中的 META-INF/spring-devtools.properties 文件都会被加载。您可以将文件打包在您的项目中,或者打包在项目使用的库中。不能使用系统属性,只能使用属性文件。 |
已知限制
重启功能与使用标准 ObjectInputStream 反序列化的对象配合不佳。如果您需要反序列化数据,您可能需要结合使用 Spring 的 ConfigurableObjectInputStream 和 Thread.currentThread().getContextClassLoader()。
不幸的是,一些第三方库在反序列化时没有考虑上下文类加载器。如果您发现此类问题,您需要向原始作者请求修复。
实时重新加载
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 文件中
-
属性
-
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 文件中不支持 profiles。 在 |
配置文件系统监视器
FileSystemWatcher 通过以一定时间间隔轮询类更改,然后等待预定义的静默期以确保没有更多更改来工作。由于 Spring Boot 完全依赖 IDE 来编译文件并将其复制到 Spring Boot 可以读取它们的位置,您可能会发现在某些情况下,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 秒轮询一次受监控的 classpath 目录以查找更改,并保持 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 支持分为两部分:接受连接的服务器端端点和在 IDE 中运行的客户端应用程序。当设置 spring.devtools.remote.secret 属性时,服务器组件会自动启用。客户端组件必须手动启动。
| Spring WebFlux 应用程序不支持远程 devtools。 |
运行远程客户端应用程序
远程客户端应用程序设计为在您的 IDE 中运行。您需要使用与您连接的远程项目相同的 classpath 运行 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 :: (v4.0.0)
2025-11-20T16:37:24.633Z INFO 128356 --- [ main] o.s.b.devtools.RemoteSpringApplication : Starting RemoteSpringApplication v4.0.0 using Java 25.0.1 with PID 128356 (/Users/myuser/.m2/repository/org/springframework/boot/spring-boot-devtools/4.0.0/spring-boot-devtools-4.0.0.jar started by myuser in /opt/apps/)
2025-11-20T16:37:24.637Z INFO 128356 --- [ main] o.s.b.devtools.RemoteSpringApplication : No active profile set, falling back to 1 default profile: "default"
2025-11-20T16:37:25.445Z INFO 128356 --- [ main] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2025-11-20T16:37:25.538Z INFO 128356 --- [ main] o.s.b.devtools.RemoteSpringApplication : Started RemoteSpringApplication in 2.05 seconds (process running for 3.205)
由于远程客户端使用与实际应用程序相同的 classpath,因此它可以直接读取应用程序属性。这就是读取 spring.devtools.remote.secret 属性并将其传递给服务器进行身份验证的方式。 |
始终建议使用 https:// 作为连接协议,以便流量加密且密码不会被截获。 |
如果您需要使用代理访问远程应用程序,请配置 spring.devtools.remote.proxy.host 和 spring.devtools.remote.proxy.port 属性。 |
远程更新
远程客户端以与本地重启相同的方式监控应用程序 classpath 中的更改。任何更新的资源都会被推送到远程应用程序,并且(如果需要)触发重启。如果您迭代的功能使用本地没有的云服务,这可能会很有用。通常,远程更新和重启比完整的重建和部署周期快得多。
在较慢的开发环境中,静默期可能不够,并且类的更改可能会分成批次。服务器在第一批类更改上传后重新启动。下一批无法发送到应用程序,因为服务器正在重新启动。
这通常表现为 RemoteSpringApplication 日志中关于上传某些类失败并随后重试的警告。但这也可能导致应用程序代码不一致,并在上传第一批更改后无法重新启动。如果您持续观察到此类问题,请尝试将 spring.devtools.restart.poll-interval 和 spring.devtools.restart.quiet-period 参数增加到适合您的开发环境的值。有关配置这些属性的信息,请参阅配置文件系统监视器部分。
| 只有当远程客户端正在运行时,文件才会被监控。如果您在启动远程客户端之前更改文件,则不会将其推送到远程服务器。 |