Spring Boot05-热部署
2026/7/19 10:21:07 网站建设 项目流程

一、Spring Boot 启动热部署

Spring Boot 启动“热部署(Hot Deployment)”,可以让你在不重启项目的情况下快速看到代码变更的效果(特别是前后端调试阶段)。


1-1、什么是热部署?

热部署是指:

修改 Java 或模板(如 HTML、Thymeleaf)代码后,无需手动重启服务,Spring Boot 能自动感知并重新加载类或资源,节省重启时间,提高开发效率。

热部署的过程:

1、重启(restart):自定义开发的代码,包括:页面,类,配置文件......,加载位置restart类加载器

2、重载(reload):jar包(基本不会有变化),加载位置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> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <!-- 只在开发环境有效 --> <optional>true</optional> <!-- 可选依赖,防止被打包进生产环境 --> </dependency>

2. 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...

这样你按Ctrl+S或切到浏览器时,IDEA 自动编译到target,devtools 自动 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、两个 ClassLoader

Spring Boot 的 DevTools 在启动时会启用两个 ClassLoader

  1. Base ClassLoader

    • 负责加载第三方依赖 jar 包(比如 Spring Boot、Spring MVC、MySQL 驱动等)。

    • 这些 jar 包一般不会在开发过程中频繁改动。

    • Base ClassLoader 在应用整个生命周期中保持不变

  2. Restart ClassLoader

    • 负责加载自己写的代码(比如ControllerService、配置文件、前端模板等)。

    • 这些内容经常在开发调试时修改。

    • 当 DevTools 监测到代码/配置变化时,会丢弃旧的 Restart ClassLoader,创建一个新的 Restart ClassLoader 来加载新的类。

重启 (restart)自定义开发的代码,包括页面、类、配置文件……,由Restart ClassLoader负责加载。

重载 (reload):jar 包(基本不会变化),由BaseClassLoader负责加载。

✔ 含义:

  • restart:只重启“自己写的代码”对应的类加载器(Restart ClassLoader)。

    • 好处:比完整 JVM 重启快很多。

  • reload:Base 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 │ └─────────────────────────────────────────────┘

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询