开发者工具
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 插件时,配置任务的类路径以包含 developmentOnly 配置。 |
诊断类加载问题
如重新启动与重新加载部分所述,重新启动功能是通过使用两个类加载器来实现的。对于大多数应用程序,这种方法都能很好地工作。但是,它有时会导致类加载问题,尤其是在多模块项目中。
要诊断类加载问题是否确实是由于 devtools 及其两个类加载器引起的,尝试禁用重新启动。如果这解决了您的问题,自定义重新启动类加载器 以包含您的整个项目。
属性默认值
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 请求的信息,所以开发工具建议您为 web
日志组启用 DEBUG
日志记录。这将为您提供有关传入请求、哪个处理器正在处理它、响应结果以及其他详细信息的信息。如果您希望记录所有请求详细信息(包括潜在的敏感信息),可以打开 spring.mvc.log-request-details
或 spring.codec.log-request-details
配置属性。
自动重启
使用 spring-boot-devtools
的应用程序在类路径上的文件发生更改时会自动重启。这在使用 IDE 时是一个有用的功能,因为它为代码更改提供了非常快速的反馈循环。默认情况下,类路径上指向目录的任何条目都会被监视是否有更改。请注意,某些资源(例如静态资产和视图模板)不需要重启应用程序。
如果使用构建插件通过 Maven 或 Gradle 重启,则必须将 forking 设置为 enabled 。如果禁用 forking,则 devtools 使用的隔离应用程序类加载器将不会创建,并且重启将无法正常运行。 |
自动重启与 LiveReload 一起使用时效果非常好。有关详细信息,请参阅 LiveReload 部分。如果您使用 JRebel,则会禁用自动重启,以支持动态类重新加载。其他 devtools 功能(例如 LiveReload 和属性覆盖)仍然可以使用。 |
DevTools 依赖于应用程序上下文的关闭钩子在重启期间关闭它。如果您禁用了关闭钩子(SpringApplication.setRegisterShutdownHook(false) ),则它无法正常工作。 |
DevTools 需要自定义 ApplicationContext 使用的 ResourceLoader 。如果您的应用程序已经提供了 ResourceLoader ,它将被包装。不支持直接覆盖 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
属性设置为触发文件的名称(不包括任何路径)。触发文件必须出现在类路径上的某个位置。
例如,如果您有一个具有以下结构的项目
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 具有可让您无需手动更新触发文件的功能。 Spring Tools for Eclipse 和 IntelliJ IDEA(Ultimate Edition) 都支持此功能。使用 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
元素是应向上拉到“restart”类加载器中的项目,而exclude
元素是应向下推到“base”类加载器中的项目。属性的值是一个正则表达式模式,该模式应用于启动时传递给 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 文件。您可以将文件打包到您的项目中,或打包到项目使用的库中。不能使用系统属性,只能使用属性文件。 |
LiveReload
spring-boot-devtools
模块包含一个嵌入式 LiveReload 服务器,可用于在资源更改时触发浏览器刷新。LiveReload 浏览器扩展程序可免费用于 Chrome、Firefox 和 Safari。您可以在所选浏览器的市场或商店中搜索“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
文件中
-
属性
-
YAML
spring.devtools.restart.trigger-file=.reloadtrigger
spring:
devtools:
restart:
trigger-file: ".reloadtrigger"
默认情况下,$HOME
是用户的 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 文件不支持配置文件。 在 |
配置文件系统监视器
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 秒轮询一次监视的类路径目录以查找更改,并保持 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 中运行。您需要使用与要连接到的远程项目相同的类路径运行org.springframework.boot.devtools.RemoteSpringApplication
。应用程序的唯一必需参数是它连接到的远程 URL。
例如,如果您使用 Eclipse 或 Spring Tools,并且您有一个名为my-app
的项目已部署到 Cloud Foundry,则您将执行以下操作
-
从“运行”菜单中选择“运行配置…”。
-
创建一个新的“Java 应用程序”启动配置。
-
浏览到
my-app
项目。 -
使用
org.springframework.boot.devtools.RemoteSpringApplication
作为主类。 -
将
https://myapp.cfapps.io
添加到“程序参数”(或任何远程 URL)。
正在运行的远程客户端可能类似于以下清单
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \
\\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) )
' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / /
=========|_|==============|___/===================================/_/_/_/
:: Spring Boot Remote :: (v3.3.5)
2024-10-24T12:03:02.454Z INFO 112504 --- [ main] o.s.b.devtools.RemoteSpringApplication : Starting RemoteSpringApplication v3.3.5 using Java 17.0.13 with PID 112504 (/Users/myuser/.m2/repository/org/springframework/boot/spring-boot-devtools/3.3.5/spring-boot-devtools-3.3.5.jar started by myuser in /opt/apps/)
2024-10-24T12:03:02.487Z INFO 112504 --- [ main] o.s.b.devtools.RemoteSpringApplication : No active profile set, falling back to 1 default profile: "default"
2024-10-24T12:03:03.165Z INFO 112504 --- [ main] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2024-10-24T12:03:03.204Z INFO 112504 --- [ main] o.s.b.devtools.RemoteSpringApplication : Started RemoteSpringApplication in 2.032 seconds (process running for 2.824)
由于远程客户端使用与实际应用程序相同的类路径,因此它可以直接读取应用程序属性。这就是读取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
参数增加到适合您的开发环境的值。有关配置这些属性,请参阅配置文件系统监视器部分。
仅当远程客户端正在运行时才会监视文件。如果您在启动远程客户端之前更改了文件,则不会将其推送到远程服务器。 |