Spring Boot05-热部署

发布时间:2026/7/19 10:21:15
Spring Boot05-热部署 一、Spring Boot 启动热部署Spring Boot 启动“热部署Hot Deployment”可以让你在不重启项目的情况下快速看到代码变更的效果特别是前后端调试阶段。1-1、什么是热部署热部署是指修改 Java 或模板如 HTML、Thymeleaf代码后无需手动重启服务Spring Boot 能自动感知并重新加载类或资源节省重启时间提高开发效率。热部署的过程1、重启restart)自定义开发的代码包括页面类配置文件......加载位置restart类加载器2、重载reloadjar包基本不会有变化加载位置base类加载器热部署仅仅代码restart过程而程序第一次启动的时候既有restart过程又有reload过程。核心概念是JVM 用两个不同的类加载器来分别处理会变动的代码和不会变的依赖。名词处理对象类加载器特点Restart重启你自己写的代码页面、类、配置文件等RestartClassLoader这些经常改需要频繁重新加载Reload重载第三方 jar 包如 Spring、MySQL 驱动等BaseClassLoader基本不变不需要重复加载1、为什么热部署快热部署时只有 Restart 过程 只重新加载你改过的那几行代码 jar 包已经在内存里了直接用不用重新读第一次启动时Restart Reload 既要加载你的代码也要加载所有 jar 包 所以启动慢2、一句话总结热部署的快是因为只重启你自己写的代码而不碰那些沉重的 jar 包依赖。第一次启动慢是因为 jar 包也要从头加载。1-2、常用热部署方式Spring Boot 推荐使用的热部署工具是Spring Boot DevTools。1-3、使用 Spring Boot DevTools 实现热部署1. 添加依赖开启开发者工具dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-devtools/artifactId scoperuntime/scope !-- 只在开发环境有效 -- optionaltrue/optional !-- 可选依赖防止被打包进生产环境 -- /dependency2. IDE 设置激活热部署Spring Boot DevTools 默认基于类文件变更触发重启即spring-boot-devtools监控的是编译输出目录target/classes不是源码目录。因此你需要确保开启 IDEA 自动编译(1). 启用了自动构建Settings → Build → Compiler → ✅ Build project automatically Settings → Advanced Settings → ✅ Allow auto-make to start even if...这样你按CtrlS或切到浏览器时IDEA 自动编译到targetdevtools 自动 Restart。(2). 让 IntelliJ 在修改文件后自动编译Advanced Settings ✔️ “Allow auto-make to start even if developed application is currently running”这样只要你保存了 Java 文件IDE 就会自动编译触发 DevTools 热部署。(3). 设置不参与热部署的文件/文件夹1-4、DevTools 热部署行为总结变更内容是否自动热部署说明Java 类Controller, Service✅ 是自动重新加载静态资源HTML, CSS, JS✅ 是即时刷新页面配置文件application.properties✅ 是配置了 DevTools 热部署 → 修改application.properties会触发自动重启→ 新配置会生效。引入新依赖❌ 否需要重新启动项目1-5、禁用热部署的功能呢1-6、DevTools 的热部署机制1、两个 ClassLoaderSpring Boot 的 DevTools 在启动时会启用两个 ClassLoaderBase ClassLoader负责加载第三方依赖 jar 包比如 Spring Boot、Spring MVC、MySQL 驱动等。这些 jar 包一般不会在开发过程中频繁改动。Base ClassLoader 在应用整个生命周期中保持不变。Restart ClassLoader负责加载自己写的代码比如Controller、Service、配置文件、前端模板等。这些内容经常在开发调试时修改。当 DevTools 监测到代码/配置变化时会丢弃旧的 Restart ClassLoader创建一个新的 Restart ClassLoader 来加载新的类。重启 (restart)自定义开发的代码包括页面、类、配置文件……由Restart ClassLoader负责加载。重载 (reload)jar 包基本不会变化由BaseClassLoader负责加载。✔ 含义restart只重启“自己写的代码”对应的类加载器Restart ClassLoader。好处比完整 JVM 重启快很多。reloadBase ClassLoader 只在程序第一次启动时加载 jar 包。之后除非你改动依赖比如改了pom.xml重新引入 jar 包否则不会再次 reload。改动类型对应过程是否自动热部署改自己写的代码、配置文件Restart✅ 自动devtools 监控target/classes改pom.xml依赖增删改 jar 包Reload❌不会自动2、启动过程和运行时的差异程序第一次启动Base ClassLoader 会reload所有依赖 jar。Restart ClassLoader 会restart你自己的业务代码。运行时修改代码/配置文件只会触发RestartClassLoader 重新创建和加载。Base ClassLoader 不变jar 不会 reload。3、总结一句热部署restart丢弃并重建Restart ClassLoader业务代码/配置/页面刷新reload 只发生在应用第一次启动时用来加载 jar 包不常变化。丢弃 让旧的 ClassLoader 及其加载的所有类变成垃圾等待 GC 回收然后新建一个干净的 ClassLoader 重新加载最新代码。JVM 的类加载有个铁律一个类一旦被某个 ClassLoader 加载就永远跟它绑定不能卸载单个类。操作能否做到原因替换UserService里的方法体❌ 不能直接做类已加载结构定死新增一个方法到已加载的类❌ 不能类结构不可变把整个 ClassLoader 换掉✅ 可以旧的连带它加载的所有类一起被 GC┌─────────────────────────────────────────────┐ │ 旧的 RestartClassLoader包含你修改前的代码 │ │ ───────────────────────────────────────── │ │ • 加载了 UserService.class旧版本 │ │ • 加载了 application.yml旧配置 │ │ • 这些类对象都在 JVM 内存里 │ │ • 一旦这个 Loader 被丢弃它加载的所有类 │ │ 都变成孤儿——JVM 垃圾回收时会清理掉 │ └─────────────────────────────────────────────┘ ↓ 检测到文件变化 ↓ ┌─────────────────────────────────────────────┐ │ 新的 RestartClassLoader加载修改后的代码 │ │ ───────────────────────────────────────── │ │ • 重新加载 UserService.class新版本 │ │ • 重新加载 application.yml新配置 │ │ • 旧的类不管了交给 GC │ └─────────────────────────────────────────────┘