热部署与 DevTools
Spring Boot DevTools 通过双类加载器 + 自动重启机制,在代码修改后数秒内完成重新加载,显著缩短开发迭代周期。
引入依赖
// build.gradle
developmentOnly 'org.springframework.boot:spring-boot-devtools'<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 不传递给依赖方,不打入生产 jar -->
</dependency>DevTools 在以下情况自动禁用,无需手动移除:生产 jar 运行(
java -jar)、完整打包的 war、单元测试运行期间(@SpringBootTest)。
核心功能
1. 自动重启(Auto Restart)
DevTools 使用双类加载器策略:
JVM
├── Base ClassLoader 加载不变的类(第三方 jar,不重启)
└── Restart ClassLoader 加载项目代码(修改后丢弃,重新加载)
监听 classpath 变化(target/classes/、build/classes/),检测到 .class 文件变化后,只重建 Restart ClassLoader,速度比冷启动快 5~10 倍。
2. LiveReload
内置 LiveReload 服务器(端口 35729),文件变化后自动通知浏览器刷新页面。需在浏览器安装 LiveReload 扩展(Chrome / Firefox 均有)。
spring:
devtools:
livereload:
enabled: true # 默认 true
port: 357293. 开发时属性覆盖
DevTools 自动应用一组开发友好的默认属性,例如:
| 属性 | DevTools 默认值 | 生产默认值 |
|---|---|---|
spring.thymeleaf.cache | false | true |
spring.freemarker.cache | false | true |
logging.level.web | DEBUG | INFO |
spring.h2.console.enabled | true | false |
这些覆盖只在 DevTools 存在时生效,不影响生产行为。
IDE 配置
IntelliJ IDEA
IDEA 默认不会自动编译,需要开启以下配置:
方式一:手动触发(稳定)
Build → Build Project(Ctrl+F9),每次改完代码手动编译一次,DevTools 检测到 .class 变化后自动重启。
方式二:自动编译(方便)
Settings → Build, Execution, Deployment → Compiler→ 勾选 Build project automaticallySettings → Advanced Settings→ 勾选 Allow auto-make to start even if developed application is currently running
开启后,焦点离开 IDEA 窗口时自动触发编译。
VS Code
安装 Spring Boot Extension Pack,它包含了 Spring Boot Dashboard 和自动重启支持。编辑 Java 文件保存后自动触发编译和重启。
触发重启的范围
默认监听整个 classpath,可精细控制:
spring:
devtools:
restart:
enabled: true
# 排除不需要触发重启的路径(静态资源变化不必重启)
exclude: static/**,public/**,templates/**,META-INF/maven/**
# 额外监听 classpath 之外的目录
additional-paths: src/main/resources
# 触发文件:只有该文件变化时才重启(配合 CI 使用)
trigger-file: .reloadtrigger触发文件(Trigger File)
适合批量修改多个文件后统一重启,而不是每改一个文件重启一次:
spring:
devtools:
restart:
trigger-file: .reloadtrigger修改完所有文件后,手动 touch .reloadtrigger(或在 IDEA 中保存该文件)触发一次重启。
全局 DevTools 配置
DevTools 支持在用户主目录下的全局配置文件,适用于所有项目:
# ~/.config/spring-boot/spring-boot-devtools.properties(macOS / Linux)
# C:\Users\<User>\.spring-boot-devtools.properties(Windows)
spring.devtools.restart.trigger-file=.reloadtrigger
spring.devtools.livereload.enabled=true远程开发(Remote DevTools)
在远程服务器上运行的应用也可以享受 DevTools 热重启,适合云端开发环境:
# 服务端(远程 application.yml)
spring:
devtools:
remote:
secret: my-dev-secret # 鉴权密钥,防止生产环境被误用服务端必须以 spring-boot-devtools 打包运行(生产模式下 DevTools 默认禁用,需显式启用):
java -Dspring.devtools.remote.secret=my-dev-secret -jar app.jar本地 IDE 中运行 RemoteSpringApplication,指向远程地址:
Run Configuration → Main class: org.springframework.boot.devtools.RemoteSpringApplication
Program arguments: https://remote-host:8080
本地代码修改 → 本地编译 → DevTools 上传 .class 到远端 → 远端重启。
DevTools vs JRebel
| 对比项 | DevTools | JRebel |
|---|---|---|
| 费用 | 免费 | 付费(商业授权) |
| 热替换粒度 | 重启 Restart ClassLoader | 真正的字节码热替换,无需重启 |
| 支持范围 | Spring Bean、配置 | 任意 Java 类,含方法签名变化 |
| 速度 | 秒级重启 | 亚秒级替换 |
| Spring 集成 | 深度集成 | 通用,需插件配合 |
| 适用场景 | 日常开发,免费够用 | 大型项目、频繁改动、追求极致效率 |
与测试的关系
@SpringBootTest 运行时 DevTools 自动禁用,不会影响测试行为。
若需要在测试中也使用 DevTools 的属性覆盖(如关闭模板缓存),可手动指定:
@SpringBootTest
@TestPropertySource(properties = "spring.thymeleaf.cache=false")
class IntegrationTest {}测试配置详见 测试。
常见问题
Q:改了代码但没有重启?
- IDEA:检查是否开启自动编译,或手动 Ctrl+F9
- 确认修改的文件在 classpath 监听范围内(不在
exclude列表) - 检查
spring.devtools.restart.enabled=true
Q:重启太频繁,每改一行都重启?
配置 trigger-file,批量改完后统一触发。
Q:生产环境误打入了 DevTools?
Maven/Gradle 的 optional/developmentOnly 配置可确保不传递依赖;java -jar 启动时 DevTools 会自动检测并禁用。
Q:DevTools 重启后 Spring Security Session 失效? 重启会销毁 JVM 内存中的 Session,可配合 Spring Session + Redis 持久化 Session,详见 Session管理。
相关链接
- 测试 —
@SpringBootTest中 DevTools 的行为 - 配置管理 — DevTools 覆盖的开发时默认属性
- Session管理 — Redis Session 持久化,解决重启后 Session 失效
- 启动流程 — 应用重启的完整流程
- 热部署与DevTools — 本文