热部署失效主因是spring-boot-devtools未生效:Spring Boot 2.6+默认禁用自动重启,需确保以mvn spring-boot:run或IDE方式启动、pom中scope为runtime、application.properties显式开启restart.enabled=true,并注意IDE自动编译与监控路径配置。

热部署没反应?先确认 spring-boot-devtools 是否真生效
很多情况下改了代码没重启,不是配置错了,而是根本没加载到 devtools。Spring Boot 2.6+ 默认禁用开发工具的自动重启(spring.devtools.restart.enabled=false),尤其在打包成 jar 运行时会彻底失效。
实操建议:
- 确保项目是通过
mvn spring-boot:run或 IDE 的「Run as Spring Boot App」启动,而非直接运行java -jar xxx.jar - 检查
pom.xml中spring-boot-devtools的 scope 是runtime还是compile——必须是runtime,否则打包时会带入生产环境 - 在
application.properties显式开启:spring.devtools.restart.enabled=true - IDE 需要启用自动编译:IntelliJ 要勾选
Build project automatically,并打开Registry → compiler.automake.allow.when.app.running
修改后不触发重启?检查文件是否在监控路径内
devtools 默认只监听 classpath 下变化,而 classpath 来源取决于你的构建方式。Maven 项目中,src/main/java 编译后输出到 target/classes,这个目录才是实际监控目标;但如果你手动改了 target/classes 里的 .class 文件,它不会触发重启——因为 devtools 监控的是资源变更事件,不是字节码差异。
常见错误现象:
- 改了
@RestController方法,但浏览器刷新没变化 → 实际是类没重新加载,可能被 IDE 编译缓存卡住 - 改了
application.yml不生效 → 默认不监听配置文件,需加配置:spring.devtools.restart.additional-paths=src/main/resources - 新增 Controller 类不识别 → devtools 不扫描新类,需手动触发 build(Ctrl+F9)或等 IDE 自动编译完成
IDEA 中热部署失败?别忽略 classloader 隔离机制
devtools 使用两个 classloader:base classloader 加载第三方 jar,restart classloader 加载应用自己的类。每次重启只丢弃 restart classloader,所以静态字段、单例对象、线程池等不会被重置——这既是优势也是坑。
使用场景与风险:
- 数据库连接池(如 HikariCP)通常由 base classloader 加载,重启后连接还在,但连接状态可能异常(比如 MySQL 连接超时断开后未重连)
- 自定义的
@Bean如果依赖静态变量或外部状态,重启后行为可能和预期不一致 - 若需完全干净重启(比如测试初始化逻辑),可临时关闭 devtools,或用
spring.devtools.restart.poll-interval和quiet-period调整检测灵敏度,避免频繁误触发
生产环境误带 devtools?检查 Maven 打包行为
只要 spring-boot-devtools 的 scope 是 runtime,Maven 的 mvn package 就不会把它打进 final jar。但如果你用了 mvn install + 本地依赖,或者某些插件(如 spring-boot-maven-plugin 配置了 includeSystemScope=true),就可能意外包含。
验证方法:
- 解压生成的 jar,执行
jar -tf target/xxx.jar | grep devtools,结果应为空 - 启动 jar 后查看日志,如果出现
LiveReload server is running on port 35729,说明 devtools 被加载了 - 更稳妥的做法:在
application-prod.yml中强制关闭:spring.devtools.restart.enabled=false,哪怕依赖存在也不起作用
最常被忽略的一点:devtools 的 LiveReload 功能依赖前端注入脚本,但现代前端工程(Vite / Webpack)通常自带 HMR,后端 devtools 的浏览器自动刷新反而会干扰,这时候应该关掉 spring.devtools.livereload.enabled=false。

















