Spring Boot + MyBatis Plus 热部署:JRebel XML 热更新完整实战

📅 发布时间:2026/9/29 19:08:12
Spring Boot + MyBatis Plus 热部署:JRebel XML 热更新完整实战
开发 Spring Boot 项目的时候最折磨人的不是写代码而是每次改完一个方法、调完一句 SQL就要盯着 IDEA 右下角的进度条等上十几秒甚至几十秒。项目大一点重启一次够泡杯咖啡。更崩溃的是你用的是 MyBatis Plus改完 XML 里的 SQL重启都未必能生效IDEA 的缓存还会跟你玩一手“老代码阴魂不散”。这篇文章就是冲着这个痛点来的我会把 JRebel 在 SpringBoot MyBatis Plus 项目里的完整接入过程、XML 热更新的实战配置、还有我踩过的那些坑一次说清楚。这篇内容适合谁正在用 Spring Boot 做业务开发、每天被无效重启消耗耐心的 Java 工程师被 MyBatis XML 文件热加载折磨过的人想在不改变团队现有框架的前提下提升开发效率的兄弟。文章不会讲太多虚的全程走一遍真实落地过程包含 JRebel 的安装激活走官方正规渠道那种、与 DevTools 的选型对比、MyBatis Plus 项目的特殊配置以及 XML 热更新失效时的排查链路。1. 为什么Spring Boot开发者迫切需要热部署先搞清楚一个底层问题我们说的“热部署”到底热在哪里。Spring Boot 应用本质上是一个独立的 Java 进程main 方法启动内嵌 Tomcat你改完代码之后IDEA 默认会帮你编译 .class 文件但这个编译动作不会替换掉已经加载进 JVM 的那个类。所以只能重启应用让 JVM 重新加载所有类。重启这件事在小型项目里也就十来秒可一旦你的项目有几十个依赖、启动时要初始化若干 Bean、连接外部中间件那一次重启的代价就被急剧放大。1.1 无效重启的代价远超你的想象很多团队一天重启几十次每次按 30 秒算一天就是将近半小时的纯等待时间。而这不是最可怕的真正可怕的是重启打断思路。你正在调试一个复杂的状态流转逻辑脑子里已经推演到第六个分支了结果改了个参数名重启等它启动完成你忘了刚才推到哪了。这种上下文切换的成本很难量化但它实实在在地拉低了开发状态。用我自己的话说重启一次不只是浪费几十秒它把你从“心流状态”里硬生生拽出来重新进入状态又得几分钟。1.2 JDK自带工具和Spring Boot DevTools解决不了根本问题很多人第一反应是IDEA 不是自带热部署吗我用过但它有几个硬伤。第一IDEA 自带的热部署只对方法体内的代码修改有效你新增一个方法、新增一个类、修改方法签名、修改注解它照样需要重启。第二它对静态资源、配置文件的支持很弱Spring Boot 的配置文件修改基本不生效。第三它在复杂项目里经常抽风改了代码没反应你还得手动 Build 一下。Spring Boot DevTools 倒是专门干这个的它通过两个 ClassLoader 的协作用 Restart ClassLoader 加载你的业务代码依赖的类由 Base ClassLoader 加载改完业务代码后只重启 Restart ClassLoader。听起来挺美但它的问题在于不是真正的方法级热替换项目一大了重启速度依然让人着急。更关键的是DevTools 对 MyBatis 场景的支持并不好XML Mapper 文件改动之后需要额外配置 spring-boot-devtools 的 restart 排除规则否则它根本不监听 XML 的变化。而且 DevTools 在一些公司的基础框架里还会引发 Bean 重复加载排查起来头大。1.3 JRebel解决的是“方法级热替换”这个核心问题JRebel 和上面这些方案有本质区别它利用了 JVM 的 Instrumentation 机制在类加载阶段做手脚通过自定义的 ClassLoader 实现类之间的依赖关系管理。说人话就是它让你的 JVM 有能力在运行状态下把新编译出来的 .class 文件替换掉已经加载的旧类而且不需要重启 JVM。这就是真正意义上的方法级热部署。改方法体、加方法、改注解、改类结构JRebel 大部分都能直接热更新。JRebel 对框架层也做了大量适配它内部有一套叫做“插件”的模块针对 Spring、MyBatis、JPA 等框架的类加载过程做了特殊处理。这就是为什么 JRebel 改完 Spring 的 Bean 之后能自动感知改完 MyBatis 的 Mapper 接口和 XML 之后也能感知。不是 JRebel 有什么玄学魔法而是它对每个主流框架的类加载机制都做了专门的适配层。提示JRebel 是收费软件但提供免费试用。市面上有一些所谓“免费激活”的路子我不建议碰一个是稳定性没保障另一个是 JRebel 会做授权校验搞不好哪天中间件就直接罢工。公司能报销就让公司买个人学习就用试用版别因小失大。2. JRebel安装与基础配置三分靠插件七分靠调优JRebel 不是一个独立软件它是 IDEA 的插件。下载安装本身很简单真正难的是装完之后怎么配置才能让你的 Spring Boot MyBatis Plus 项目舒服地跑起来。2.1 安装与基础设置打开 IDEA在 Settings 里找到 Plugins搜索 JRebel找到 JRebel and XRebel for IntelliJ点击 Install装完重启 IDEA 即可。重启之后你的工具栏上会多出两个绿色的按钮——一个带 JRebel 图标的锤子一个带 JRebel 图标的爬虫。爬虫那个是 XRebel性能分析用的平时用不上。重点是那个锤子按钮以后启动项目不点绿色三角改点这个带 JRebel 图标的锤子这样项目才会以 JRebel 模式启动。安装完成之后进入 Settings - JRebel先勾选 Build Project on frame deactivation 选项。这个选项的作用是当 IDEA 窗口失去焦点时自动帮你编译项目。JRebel 的热部署是基于编译产物的也就是说IDEA 帮你在后台把改动过的代码重新编译JRebel 发现 class 文件变化后才会触发替换。如果你用的是 Maven 或者 Gradle也可以在终端里手动执行 compile效果是一样的。但 IDE 自动编译更省事我强烈建议勾上。在同一个面板里还有个选项叫 Compile independent modules in parallel如果你的项目是多模块结构建议勾上可以加速编译。另外版本较新的 JRebel 会让你选择 Compiler 版本保持 IDEA 默认的 javac 就行。2.2 激活途径的选择JRebel 的激活方式我只推荐两种一种是官方试用注册个账号能免费用十四天还是二十一天来着适合临时体验一种是公司采购 license server在激活界面填服务器地址和邮箱即可。JRebel 激活后的授权是绑定邮箱的你换电脑之后用同一邮箱重新激活能找回授权。激活的过程很简单Settings - JRebel - Activation选择 Connect to license server填入公司提供的 license server URL下方输入你的邮箱点击 Activate几秒钟就完事。激活后界面上会显示当前授权类型、到期时间等信息。注意JRebel 插件装完不是对所有项目都生效。你要在 IDEA 右侧或者 Settings 里找到 JRebel 面板里面会有当前项目的 Modules 列表每个 Module 前面有一个复选框必须勾上这个模块才会被纳入 JRebel 管理。经常有人装完插件发现热部署没反应一看原来是模块没勾选。2.3 JRebel与DevTools怎么选我直接给结论两个不要同时用。DevTools 和 JRebel 都会对类加载机制做处理同时存在的时候经常出现 Bean 重复加载、类的实例状态不一致的问题排查起来非常痛苦。如果你决定用 JRebel就把 pom.xml 里的 spring-boot-devtools 依赖移除干净。JRebel 的诊断工具会打印出当前项目的 ClassLoader 分布DevTools 存在时会有明显的干扰。选型上的建议个人开发者项目简单可以用 DevTools 先顶着毕竟免费。但如果你和我一样天天跟 MyBatis XML、Spring Bean 打交道JRebel 的体验确实是天壤之别。特别是改 XML 不用重启这一条就值回票价了。3. JRebel热部署的原理深挖为什么MyBatis的XML是天然的坎JRebel 能实现热部署核心靠的是它对 JVM 类加载机制的深度干预。要理解后面 XML 热更新的配置你得先搞明白这层原理。我尽量讲得通俗一点用的是 JVM 层级的概念但其实没有想象中那么玄。3.1 类加载机制里的“狸猫换太子”Java 的类加载过程是委托机制一个类要加载进内存会先交给父加载器处理父加载器搞不定才自己来。JRebel 的思路是在这个链条上插入一个自定义的 ClassLoader。这个 ClassLoader 负责加载你的业务代码而且它维护了一个“类名 - 字节码”的映射关系。当你改完代码IDEA 编译产生新的 .class 文件JRebel 发现文件的 hashCode 变了就通过这个 ClassLoader 把新字节码重新加载一遍替换掉 JVM 里那一个旧的类版本。这个过程有个很关键的点JRebel 不是把旧类“抹掉”而是让新的类定义覆盖旧的。这样一来旧的对象实例如果还存活在内存里它的下一次方法调用就会走到新的字节码上。所以你不需要重启之前创建好的 Bean 、已经建立好的连接池都不会被销毁重建这也是 JRebel 比 DevTools 优越的根本原因。3.2 为什么 XML 文件不能直接套用这套机制问题来了类加载机制管的是 .class 文件但 MyBatis 的 Mapper XML 是资源文件它不经过类加载器。MyBatis 在启动阶段会把 XML 解析成一个又一个 MappedStatement 对象存进 Configuration 对象里。这个 Configuration 是单例的整个 SqlSession 生命周期内都复用同一个实例。你改完 XMLJRebel 能监听到文件变化但 MyBatis 已经把旧的 SQL 语句固化成对象了不会自动去重新解析 XML。这就是很多人在 MyBatis 项目里直接用 JRebel 发现“热部署了个寂寞”的原因。类和方法能热替换但 SQL 语句纹丝不动。你得让 MyBatis 感知到 XML 变了并且主动刷新 Configuration 里的 MappedStatement。这里有一个框架设计上的天然矛盾也是 XML 热更新配置存在的意义。3.3 JRebel对MyBatis的扩展机制JRebel 其实内置了对 MyBatis 的适配插件它会在 MyBatis 初始化的时候注入一些监听器。这些监听器会监测 XML 文件的变化一旦发现 XML 文件被修改就触发一个刷新流程重新加载 XML替换掉旧的 MappedStatement。但这里有个前提条件JRebel 必须能感知到 XML 文件所在的路径并且在 IDE 里正确关联到这个路径。这个前提条件就是所有 XML 热更新配置的核心。4. Spring Boot MyBatis Plus 项目接入JRebel完整实操现在进入正题我以目前公司项目为例技术栈是 Spring Boot 2.7.x MyBatis Plus 3.5.x Maven 多模块工程通过实战演示整个接入过程。这个项目比较典型有 common 模块、dal 模块、biz 模块、web 模块热部署的难点集中在 dal 模块的 Mapper XML 上。4.1 清理环境去除DevTools依赖第一步检查项目里有没有 spring-boot-devtools。如果有直接删除依赖。!-- pom.xml 中移除或注释掉这段 -- !-- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-devtools/artifactId optionaltrue/optional /dependency --这里多说一句devtools 在 classpath 里是通过 spring.factories 自动配置的你光在 IDEA 里禁用还不够必须从依赖层面摘除。否则 JRebel 报告里会出现 ClassNotFoundException 或者 NoClassDefFoundError很莫名其妙。4.2 检查JRebel模块勾选打开 IDEA 右侧的 JRebel 面板你会看到当前项目涉及的所有 Module 列表。确保 web 模块、biz 模块、dal 模块、common 模块全部打勾。如果某个模块是纯资源模块比如放静态文件的可以不勾但 Java 模块必须全勾。这一步漏掉的话最典型的现象是改 web 模块的 Controller 能热部署改 dal 模块的 Mapper 死活没反应。排查到后面才发现是 JRebel 根本没管理这个模块。4.3 配置 mybatis-plus 的 XML 路径与缓存策略接下来是 XML 热更新的重头戏。在 application.yml 里MyBatis Plus 相关的配置如下mybatis-plus: mapper-locations: classpath*:/mapper/**/*.xml configuration: map-underscore-to-camel-case: true global-config: banner: false db-config: id-type: auto这里有个至关重要却不被重视的参数是 configuration 下的 default-scripting-language如果你用了自定义的 SQL 注入器或脚本语言驱动也要注意不要被热更新搞乱。不过大部分项目用不上重点还是 mapper-locations。JRebel 的 MyBatis 插件要能监听到 XML 变化前提是它知道 XML 的物理路径。如果你的项目把 XML 放在 src/main/resources/mapper 下面默认是能感知到的。但如果你像我一样把 XML 放在 src/main/java 的某个包里那就必须确保 Maven 的资源配置把 XML 也打包进去。这块在 pom.xml 里这样写build resources resource directorysrc/main/java/directory includes include**/*.xml/include /includes /resource resource directorysrc/main/resources/directory /resource /resources /build4.4 关键配置禁用MyBatis Plus的XML热加载缓存到了这里很多人以为配置完了结果一测XML 还是不能热更新。问题出在 MyBatis Plus 的 Configuration 上。MyBatis Plus 在 3.5.x 版本里对 MappedStatement 的缓存粒度做了调整JRebel 的监听器不一定能覆盖到所有刷新场景。我推荐一种更稳妥的方案手动开启一个 XML 热更新监听器。思路是利用 Spring 的事件机制监听 Resource 目录下 XML 文件的变化一旦发现变化就调 MyBatis 的 XMLMapperBuilder 重新解析 XML刷新 MappedStatement。Component public class MybatisXmlHotReloadListener implements ApplicationListenerContextRefreshedEvent { private static final Logger log LoggerFactory.getLogger(MybatisXmlHotReloadListener.class); private final SqlSessionFactory sqlSessionFactory; private final MybatisPlusProperties mybatisPlusProperties; private final ResourceLoader resourceLoader new DefaultResourceLoader(); public MybatisXmlHotReloadListener(SqlSessionFactory sqlSessionFactory, MybatisPlusProperties mybatisPlusProperties) { this.sqlSessionFactory sqlSessionFactory; this.mybatisPlusProperties mybatisPlusProperties; } Override public void onApplicationEvent(ContextRefreshedEvent event) { // 启动时把 XML 文件缓存起来注册一个文件监听器 Configuration configuration sqlSessionFactory.getConfiguration(); String[] mapperLocations mybatisPlusProperties.getMapperLocations(); if (mapperLocations null || mapperLocations.length 0) { return; } // 这里省略具体实现 // 关键逻辑每隔2秒扫描一次XML文件最后修改时间变化则重新build } }这段代码我故意省略了完整实现因为不同项目的目录结构和监听方式不一样。核心思路就是应用程序启动完成后把 XML 文件的路劲和最后修改时间存到一个 Map 里然后用一个定时任务每两秒检查一次。如果有文件变了就调用 XMLMapperBuilder.parse() 方法把新的 MappedStatement 刷进去。如果你的项目里引入了 spring-boot-starter-actuator还可以通过 endpoint 手动触发 XML 刷新这个思路适合运维团队做 SQL 灰度调整开发阶段用不着。4.5 验证热部署是否真正生效配置完之后来一次完整的验证流程。首先用 JRebel 模式启动项目启动日志里会有醒目的 JRebel banner 和一行“Starting Spring Boot Application with JRebel”的字样。然后改一个 Controller 方法比如加一个返回值IDEA 窗口失焦后 JRebel 会自动编译并热替换日志里出现“Reloading class com.xxx.controller.UserController”之类的信息这就说明类层面的热部署生效了。再改一个 XML 里的 SQL比如把查询条件从status 1改成status 2在浏览器或者 Postman 里重新调用接口观察日志。如果 XML 热更新成功日志里会出现类似“Reloaded MappedStatement”或者 MyBatis 相关的 debug 日志而且接口返回的数据会发生变化。如果数据没变说明 XML 没有被重新解析或者被 SqlSession 缓存住了。5. XML热更新失效排查我在实战中踩过的三个大坑这部分是我写这篇内容的初衷。JRebel 的热部署在很多 Spring Boot 项目里能直接跑起来但到了 MyBatis Plus 场景总有一些稀奇古怪的问题。我把实战中遇到的三个典型问题一一拆解顺便把排查链路讲清楚方便你照着做。5.1 坑一IDEA的Build机制导致XML文件没被重新编译现象改完 XMLJRebel 有反应但 MyBatis 报错说找不到某个 SQL id或者执行的是旧 SQL。排查链路先看 target/classes 目录下的 XML 文件有没有被更新。如果你用的是 Maven 的 resources 插件IDEA 的 Build 不一定触发 resources 重打包。在 IDEA 的 Build 菜单里勾选 Build project automatically再配合 JRebel 的 Compile independent modules in parallel会稍微好一点。但还是不够稳妥。我的解决方案把项目从 Maven 的默认构建模式切换为 IDEA 构建模式。在 Settings - Build Tools - Maven 里把 Runner 下的“Delegate IDE build/run actions to Maven”去掉。这样IDEA 的 Build 操作会按自己的逻辑走而不是委托给 Maven资源文件的更新速度会明显提升。但是要注意这个选项去掉之后IDEA 的构建逻辑必须能正确处理 resources 目录下的文件所以 4.3 小节里 pom.xml 的 resources 配置必须保留。5.2 坑二MyBatis Plus的分页插件在热更新后失效现象用了 MyBatis Plus 内置的分页插件 PaginationInnerInterceptorXML 热更新一次之后分页查询的 count 语句不生效了返回的 total 是 0。原因分析JRebel 重新加载 MappedStatement 时MyBatis 的 Interceptor 链没有对新加载进来的 MappedStatement 做拦截包装。因为分页插件本质上是在 Executor 层面做拦截但 MappedStatement 里存的 BoundSql 和参数处理逻辑是组装在 SQL 里的热更新后旧的拦截结果被重置了。解决思路分页插件拦截的是 Executor.query 方法MappedStatement 重建之后理论上 Interceptor 会重新走一遍。实测中发现问题出在 MyBatis Plus 的 XmlResourcePatternResolver 上它缓存了旧的 XML 解析结果。在配置类里加一行强制刷新逻辑Bean public ConfigurationCustomizer mybatisPlusConfigurationCustomizer() { return configuration - configuration.setSafeResultHandlerEnabled(false); }这个方法实际没有解决根本问题真正的做法是把分页拦截器重新注册一遍。我提供一个比较 hack 的解决方案在热更新定时器触发 XML 重新解析之后再调用一次 MybatisPlusInterceptor 的 getInterceptors 方法强制刷新内部缓存。5.3 坑三多模块项目中XML路径被错误解析现象web 模块启动JRebel 能热部署 Mapper 接口但 XML 改了半天不生效。打开日志发现JRebel 报“Resource is not in project”或者 MyBatis 报了 Mapper statement not found。原因分析在多模块项目里Maven 的 classpath*: 匹配范围可能把多个模块的 mapper 目录都扫进来了而 JRebel 监听的路径只覆盖部分模块。特别是在合并打包的情况下XML 文件可能存在于两个位置MyBatis 加载了旧的那个。解决方案在 mybatis-plus 的 mapper-locations 里写成classpath:dal-module-name/mapper/**/*.xml明确指定 XML 所在的模块不要用 classpath*。虽然 classpath* 更保险但在热部署场景下它的模糊性会放大 JRebel 的监听路径偏差。5.4 坑四JRebel和Lombok的兼容性问题还有一个很容易被忽略的问题JRebel 和 Lombok 的配合。Lombok 在编译阶段通过注解处理器生成 getter/setter、构造器等代码。JRebel 热部署时如果 Lombok 生成的代码结构发生变化比如你给实体类加了一个字段JRebel 可能加载了不完整的类定义导致运行时报 NoSuchMethodError。排查思路看 IDEA 的 Build 日志里有没有 Lombok 相关的 warning最好升级到 JDK 8 对应版本的最新 Lombok并在 pom.xml 里给 Lombok 的注解处理器加上 provided 作用域。还有一种情况是 IDEA 的注解处理器开关没打开在 Settings - Build, Execution, Deployment - Compiler - Annotation Processors 里勾选 Enable annotation processing否则 Lombok 生成的代码可能在 JRebel 模式下无法正常生成。6. JRebel性能优化与团队协作的落地细节配置热部署只是第一步真正上线到团队多人协作环境还有不少细节要处理。我在这块吃过亏花点篇幅讲讲。6.1 如何避免JRebel拖慢前端调试接口的速度JRebel 模式下IDEA 的 Build 线程和 JRebel 的类替换线程并行运转如果你前端联调时频繁改 CSS、JS这些静态资源变化也会触发 JRebel 的检测虽然不影响类加载但会给编译线程增加压力。解决方案是在 JRebel 面板里配置 Exclude 规则把**/*.css、**/*.js、**/*.html、**/*.vue排除掉让 JRebel 对这些文件不做监听。前端资源的更新交给浏览器的 live reload 插件处理各管各的。同理**/test/**和**/resources/**这些非运行时代码也建议排除。6.2 如何保证团队所有成员的热部署行为一致JRebel 的配置存在每个开发者的本地 IDEA 中不同人的配置不一样就会出现“在你机器上热部署 OK在我机器上不行”的问题。为了统一行为我建议把 JRebel 的关键配置项写进项目的 .idea 目录中随 Git 一起提交。具体来说在项目根目录的 .idea 文件夹下有一个 jrrebel.xml 之类的配置文件里面记录了模块的勾选状态。如果团队里有人误操作把模块勾选去掉提交代码时会出现冲突反而能引起大家注意。当然更靠谱的做法是写一份简短的 README放在项目根目录把 JRebel 的启动方式、编码规范、常见问题的排查链接统一放进去。新同事入职后照着操作能在十分钟内搞定开发环境。这种隐形基建往往比写了一堆业务代码更能提升团队效率。6.3 性能监控JRebel不是所有类都要热替换有些人装完 JRebel发现热部署是快了但运行一段时间之后内存涨得厉害。这是因为 JRebel 维护的类版本映射表不断膨胀。如果你的项目里有一个定时调度类每次运行都会重新生成新类定义JRebel 会保留很多旧版本引用GC 回收不掉。解决办法是在 JRebel 的配置里开启 Release unused classes 功能让 JRebel 在类不再被引用时自动释放。同时把那些运行频率极高、改动频率极低的类排除掉比如**/config/**、**/entity/**下的类静态配置型的实体类基本不会动不需要参与热部署。6.4 JRebel日志的查看与自我诊断JRebel 自己带了一套诊断工具在 IDEA 里运行项目时打开 JRebel 的 Console 标签页里边会打印很详细的热部署日志。日志里能看到每个类的加载状态是“Skipped”还是“Reloaded”以及耗时多少。正常热部署耗时在 100ms 到 500ms 之间如果某个类达到秒级说明类依赖太复杂或者触发了框架的全局刷新。遇到诡异问题比如某个类改了但运行没变化先看日志里有没有错。JRebel 的日志默认是 INFO 级别可以调成 DEBUG设置方式是在 JRebel 面板里勾选 Enable debug logging重启项目生效。DEBUG 日志会打印出每个类的加载决策排查起来非常直观。7. 热部署之外MyBatis Plus项目的开发效率还能怎么提升这一节算是一点点扩展。JRebel 只是开发提效里的一环它解决的是“改代码后等待”的问题但 MyBatis Plus 项目里还有一些日常开发中的低效点值得顺手优化。7.1 开启MyBatis Plus的SQL日志输出调试 SQL 的时候与其反复去数据库工具里复制粘贴不如在项目里把 SQL 日志直接打开。在 application.yml 里配置日志级别logging: level: com.yourcompany.project.mapper: debug这里把 Mapper 接口所在的包设为 debug 级别MyBatis 会打印 SQL 语句、执行参数、返回行数。配合 JRebel你改完 SQL 热部署后刷新一下接口日志里的新 SQL 立刻就能看到对比修改前后的差异非常方便。这对排查 XML 热更新是否生效也有辅助作用。7.2 使用MyBatis Plus的条件构造器减少XML编写XML 热更新再顺滑也不如不写 XML。MyBatis Plus 的一大优势是通用 Mapper 提供了一整套条件构造器日常的 CRUD 操作可以完全告别 XML。比如动态条件查询用 LambdaQueryWrapper 比写if标签舒服多了。当然复杂报表类的 SQL 还是要写 XML 的这没办法。我的习惯是能用条件构造器解决的就用构造器几十行以上的动态拼接才考虑 XML这样 XML 数量少热更新的压力也小。7.3 合理使用MyBatis Plus的代码生成器还有一个我强烈推荐的实践用 MyBatis Plus 的代码生成器MyBatis-Plus Generator自动生成实体类、Mapper 接口、Service、Controller 的初始版本。虽然生成的代码风格不一定完全符合团队规范但至少能省掉机械敲击的时间。生成完之后手工调整命名和业务逻辑整体效率提升非常明显。而且这些东西生成出来之后几乎不用改 XML进一步降低热部署的依赖面。8. 写在最后的一些经验之谈JRebel 这个东西说实话不是必需品但一旦用上再让你回到每天重启开发的节奏你会觉得浑身难受。它给我的感觉就像是从机械硬盘换到固态硬盘单次操作省下来的时间不多但累积起来非常惊人。如果你正在用 Spring Boot MyBatis Plus且厌倦了每次改 SQL 都要重启我建议你花一个下午的时间按照这篇文章的步骤把它配好。中间如果遇到 XML 不生效的问题不要慌对照第 5 小节的排查链路一个个看大概率能解决。以后开发的时候你会发现自己对代码的修改频率都变高了——因为试错的成本低了你更敢改、更愿意改。这才是热部署真正的价值它不只是省时间它还降低了你探索代码的自由度成本。最后提醒一句JRebel 的授权方式、插件版本和 IDEA 版本强相关升级 IDEA 或 JRebel 之前先去官方文档看一眼兼容性列表免得升完级热部署失效还要回头排查。我的习惯是IDEA 大版本更新后先让 JRebel 用旧版本跑一周确认没问题再升级稳字当头。