
每周一早上十点办公室里大概率会响起这样的声音“谁改代码了重启一下”“等一下我还没改完先别重启”这种场景我们太熟悉了。Java Web开发里改一行代码就要重启应用轻则等几十秒重则等几分钟一天下来光等启动就耗掉一两个小时。Spring Boot热部署就是冲着这个痛点来的——代码改了应用自动重新加载不用手动重启开发效率直接上一个台阶。这篇内容我想好好聊一聊Spring Boot热部署这件事。不光是教你怎么配置还会把背后的原理、方案的取舍、实操中的坑都讲透。适合正在用Spring Boot做开发、整天被重启折磨的朋友也适合那些想搞清楚devtools、JRebel这些工具到底怎么回事的读者。内容会保持“干活”的风格不绕弯子直接说怎么做、为什么这么做。1. 热部署到底解决了什么问题1.1 每次重启浪费的到底是什么很多人对热部署的认知停留在“省时间”这三个字上但省下来的时间远比想象中多。一个中等规模的Spring Boot项目冷启动通常需要20到60秒如果是大型微服务项目依赖了注册中心、配置中心启动时间可能就奔着两三分钟去了。这里面包含了Spring容器的初始化、Bean的创建、数据库连接池的建立、各种自动配置的装载每一步都是实打实的开销。更关键的是重启不只是“等启动完成”这么简单。启动完成之后还要人工去复现一遍操作路径——打开登录页、输入账号密码、点进目标页面、触发那个需要验证的接口。这一套流程下来一次重启消耗的时间成本往往是把代码编译时间、应用启动时间、人工操作时间加在一起算的。热部署解决的就是这个问题——把“改代码 → 重启 → 重新操作”这个循环缩减为“改代码 → 自动生效 → 直接刷新页面验证”。对于那种调试一个复杂业务流程的场景比如订单状态流转、审批流程、接口参数调整热部署带来的体验提升是质变级别的不是量变。1.2 热部署、重载、重启这三者不是一回事在做方案选型之前先把概念理清楚。很多人把“热部署”“热重载”“热更新”混着说其实它们在技术实现和适用场景上有明确区别。重启Restart最粗暴的方式整个JVM进程退出重新启动。Spring容器完全重新初始化所有Bean重新创建进程内的状态全部丢失。这是最早的方式也是效率最低的方式。热重载Reload应用进程还在但应用上下文ApplicationContext被重新创建。Spring Boot的DevTools用的就是这种思路它会把当前类加载器拆分成两个一个加载稳定的第三方依赖一个加载开发者自己写的类。开发者改了代码之后只销毁和重建那个加载业务类的类加载器依赖的类加载器保持不变。这样比整个重启快得多但本质上Spring容器还是重新初始化了一遍。热替换Hot Swap最理想的方式直接在JVM层面用字节码替换掉指定的类不重建Spring容器不销毁类加载器类的状态尽可能保留。这就是JRebel这类商业工具的核心能力也是IDE自带的Debug模式HotSwap功能的基础。有一个类比可以帮助理解重启相当于整个机房断电重新开机热重载相当于只重新启动机房里的一个业务系统而热替换相当于系统运行中直接换掉一块正在工作的硬件模块旧模块的接线状态还保持着。实际开发中这三种方案各有适用场景后面会详细拆解。2. 方案盘点与选型逻辑2.1 不用花钱的组合Spring Boot DevToolsSpring Boot官方提供的DevTools是入门首选一个依赖就能集成零成本、无侵入。它做的事情包括三项自动重启、LiveReload自动刷新浏览器、开发期的一些统一配置增强。自动重启的原理就是前面提到的双类加载器机制它用两个ClassLoader把项目的依赖和业务代码分开加载监控到classpath下的文件发生变化时只重启存放业务类的那个类加载器避免全部重新加载的开销。但是DevTools有一个很要命的限制它只对classpath下发生变化的内容生效。你改了Java代码IDE帮你编译成新的.class文件DevTools检测到class文件变化触发重启。可如果你改的是配置文件比如application.yml、自定义的properties文件这些也放在classpath下DevTools默认也会触发重启。改静态资源比如HTML、JS、CSSDevTools默认不重启只是让浏览器自动刷新一下。实测下来DevTools在对中小型项目的体验是比较好的。项目依赖少、启动快重启只要几秒钟配合浏览器的自动刷新日常开发完全够用。但这套方案对大型项目就有点力不从心一个启动就要1分钟的项目用了DevTools也还是要等因为它本质上没有免除Spring容器的重新初始化。2.2 花钱买效率JRebel这类商业工具JRebel是一个老牌的JVM热部署工具核心能力是字节码层面的类热替换。它通过一个Java Agent在类加载时拦截并改写字节码让类在运行中替换时不需要重新创建Spring容器。改一个Controller方法、改一个Service实现JRebel直接替换对应类的字节码应用程序上下文完全不需要动相当于把热重载的粒度和开销都优化到了极致。JRebel对Spring Boot的支持非常成熟包括对Spring注解的变更、新Bean的注册、配置文件的一些变更都能处理。它甚至支持在新增一个带Autowired依赖的类之后动态注入这个依赖。这一点DevTools就做不到DevTools遇到新增Bean的场景还是得走一次上下文刷新。商业工具确实花钱JRebel按年订阅个人授权和商业授权价格不同。但很多团队算过这笔账如果团队里有5个后端开发每人每天平均重启10次每次省2分钟一天就是100分钟一个月就是2000多分钟——这还不算重启完了重新走业务流程的时间。从投入产出看这类工具对重度Java开发是值得的。不过JRebel有一个需要注意的问题它是一个字节码增强工具对某些框架版本或JDK版本的兼容性会滞后。当年从JDK 8切到JDK 11、JDK 17时JRebel的适配就出现过空档期老版本可能直接起不来。使用商业热部署工具要保持对版本兼容性的关注不能无脑升级JDK。2.3 IDE自带的HotSwap和DevTools怎么配合IDEA和Eclipse在Debug模式下都支持HotSwap也就是JVM的Instrumentation机制在调试会话里直接替换变更的方法体。这是JDK层面的能力不需要额外依赖但它有一个明显的限制只能替换方法体不能新增方法、不能改方法签名、不能新增字段。改一个方法内部逻辑没问题往类里加一个方法或者加一个字段HotSwap就提示“Cannot Hot Swap”。所以理想的做法是IDE的HotSwap负责“小改动”改方法体直接生效DevTools负责“大改动”新增了类、改了结构自动触发重启。两者结合大多数开发场景都能覆盖。实际开发中我把IDEA的设置改成“Build project automatically”配合DevTools编译完成之后自动重启大部分时间手都不用离开代码。2.4 Spring Boot 2.x和3.x在热部署上的差异Spring Boot 3.x基于Jakarta EE和Spring 6对热部署的支持方式和2.x基本一致DevTools在两代版本里都有官方维护。但Spring Boot 3.x强制要求Java 17这意味着对JDK版本兼容性更敏感。JRebel从某个版本开始才完整支持JDK 17的字节码增强如果项目用了Spring Boot 3.2以上的版本搭配新JDK务必确认JRebel版本够新否则可能出现热替换不生效或应用启动异常的情况。另外Spring Boot 3.x在配置管理上做了一些改变比如自定义配置数据、Config Data API的调整DevTools对这些配置项的支持逻辑也有所不同。建议直接在项目的官方文档里查对应版本的DevTools说明不要照着2.x的旧教程硬套。3. Spring Boot DevTools实操从配置到避坑3.1 最小化集成一个依赖加一个配置DevTools的集成非常简单Maven项目在pom.xml里加依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-devtools/artifactId scoperuntime/scope optionaltrue/optional /dependency注意两个细节。scope设置为runtime表示这个依赖只在运行时需要编译时不会被引用到业务代码里optional设置为true是为了避免DevTools被传递到下游模块。如果这是一个多模块项目不标optional其他模块也会带上DevTools导致不必要的自动重启。Gradle项目的话则是dependencies { developmentOnly org.springframework.boot:spring-boot-devtools }加完依赖之后直接用IDE启动项目没有额外操作。但要真正实现“改完代码自动重启”需要确保IDE一边编译、DevTools一边检测。IDEA里需要打开一个设置Settings → Build, Execution, Deployment → Compiler → Build project automatically勾上。还有高级一点的配置按快捷键Ctrl Shift Alt /调出Registry面板勾上compiler.automake.allow.when.app.running。这个配置是让应用运行的时候IDEA也允许自动编译。有些文章会把这两步混为一谈不勾Registry里那项光勾Build project automatically实测下来编译并不会在应用运行期间自动触发代码改了也没反应。这个坑我踩过写出来提醒一下。3.2 配置项详解哪些需要调、哪些别乱调DevTools支持通过spring.devtools.restart.*配置项控制自动重启的行为。常用配置如下# 关闭自动重启 spring.devtools.restart.enabledfalse # 额外监控的路径 spring.devtools.restart.additional-pathssrc/main/java # 排除掉不需要触发重启的路径 spring.devtools.restart.excludestatic/**,public/** # 自定义触发文件 spring.devtools.restart.trigger-file.trigger第一个配置顶多是全局关掉自动重启通常用于生产环境不希望DevTools生效的场景。这里多说一句DevTools在打包成可执行Jar时是自动失效的因为scoperuntime不会被打进Spring Boot的repackage包里所以不需要刻意在生产环境配置关闭。但如果用java -jar运行本地构建的包且这个包是通过mvn spring-boot:run跑出来的目录形式DevTools是有可能生效的这种情况建议显式关闭。additional-paths和exclude是一对配合使用的设置。比如项目里源码在src/main/javaMyBatis的Mapper XML在src/main/resources/mapper下Mapper XML也属于需要触发重启的内容它默认就在classpath里不需要额外配置。但如果你的Mapper XML放在src/main/java目录下而不是resources里就一定要加additional-paths把它的变化也纳入监控。反过来静态资源目录像static、public下面内容变化不应该触发重启用exclude排除掉这样改前端页面时不会白白重启后端服务。trigger-file是一个比较小众但很有用的配置。指定一个触发文件当这个文件被修改时才触发重启。适合什么场景呢多人协作时你正在写一段代码代码一直在变你不希望每保存一次就重启一次可以先把自动重启关掉或调整成触发文件模式等代码写到一个阶段性完成的状态touch一下触发文件重启一次统一验证效果。3.3 DevTools的三个隐藏功能第一个是LiveReload。DevTools自带一个LiveReload服务器前端页面修改后浏览器自动刷新。配合Chrome的LiveReload插件改完HTML/CSS/JS直接看效果连刷新都不用点。Spring Boot 3.x里这个功能默认也是开启的端口号是35729。第二个是远程应用的热重启支持。DevTools支持一种“远程应用”模式本地代码修改后自动同步到远程运行中的应用并触发重启。涉及一个密钥配置spring.devtools.remote.secretmy-secret启用远程连接会让应用暴露一个远程更新端口有一定安全隐患。生产环境绝对不要开这个功能只适合开发环境远程调试的场景。操作步骤是远端应用以特殊方式启动本地用org.springframework.boot.devtools.RemoteSpringApplication指向远端地址实现远程重启。步骤稍繁琐用得少这里就不展开每个细节了。第三个是默认关闭的日志相关优化。DevTools启动后会调整部分日志级别让启动信息更清晰简洁同时把Thymeleaf等模板的缓存默认关掉这样模板改动能立即生效。这个是Spring Boot中对开发体验的全面优化不只是“重启”这一个点。3.4 DevTools的副作用和解决思路DevTools自动重启最大的副作用应用上下文会重新初始化所有单例Bean都会重建。如果项目里有数据缓存在内存中、有WebSocket连接、有定时任务正在执行自动重启后这些状态都会丢。定时任务如果配置了cron表达式项目重启后任务会按新的时间重新调度可能会造成重复执行或者漏执行。解决思路是尽量把需要跨重启保留的状态放到外部存储里比如Redis、数据库。内存在开发环境里本来就不作为可靠存储如果开发中依赖了内存缓存来验证功能可以考虑调试时不启用缓存直接用真实存储。DevTools重启之后Spring容器重新创建实际上最接近一次完整的应用重启它并不能帮你保留会话数据。对session的保持可以配合IDEA的“Rerun”功能让浏览器保存的session继续用但应用端的session状态是不保留的。还有一点DevTools与Spring Security、OAuth这种基于内存token状态的框架结合时自动重启会让登录态失效。开发时频繁打token确实挺烦人。我的做法是开发环境关闭CSRF、关闭安全拦截或者使用固定测试Token的配置避免被重启打断调试节奏。3.5 Spring Boot 3下的DevTools配置细节Spring Boot 3.2之后自动配置机制做了一些重构但DevTools的核心行为没变。有一个小变化是新增了spring.devtools.restart.enable这个属性早期版本是enabled配置为false可以完全关闭重启能力但DevTools的其他能力如LiveReload仍然生效。使用Spring Boot 3的项目建议在配置文件中写明版本对应的属性名避免配置不生效。还有一个容易忽视的点Spring Boot 3 Java 21的环境下DevTools的自动重启依赖对classpath文件变更的轮询检测默认有一个重试机制spring.devtools.restart.poll-interval如果文件监控不稳定可以调低轮询间隔比如改成500ms。这个参数在大型项目里对“改了没反应”这类问题有奇效。4. JRebel与第三方方案花钱买更顺滑的体验4.1 JRebel的工作机制和配置要点JRebel的使用方式不是改Maven依赖而是作为一个JVM Agent启动。IDEA安装JRebel插件之后在Settings里找到JRebel的License配置输入激活信息然后通过“JRebel Run”按钮启动应用而不是普通的Run按钮。JRebel会在JVM启动参数里加上-javaagent:/path/to/jrebel.jar它的核心机制是类加载完成后JRebel在内存里保存了一份类的最新字节码当检测到class文件变化时直接用新的字节码替换旧的不需要重建Spring容器。这个过程快得是毫秒级的。配置JRebel的关键在于在网络畅通的情况下插件会自动检测Spring Boot项目结构为Spring Boot应用提供自动配置。但你需要在IDEA的JRebel面板确认所有Module都处于激活状态如果某个Module没被勾选改动那个Module下的类不会触发热替换。4.2 JRebel和DevTools能一起用吗能但不建议。两者的定位有重叠同时启用会出现问题。DevTools会在类加载器层面做隔离一旦重启触发整个DevTools的类加载器就会被重建JRebel的字节码替换目标就指向了已经废弃的类加载器导致热替换失效或者抛出奇怪的类转换异常。我的建议是用了JRebel就关掉DevTools。在pom.xml里把DevTools依赖注释掉或者至少设置spring.devtools.restart.enabledfalse。JRebel本身已经覆盖了DevTools的大部分能力还更快没必要两套都在跑。4.3 JRebel的激活问题与正版化提示这里必须多说一句关于激活的事。网上确实有不少关于JRebel激活的教程但JRebel最近几个版本对激活服务器的校验越来越严格很久之前流传的那些“无限试用”“离线激活”方案基本都失效了。用盗版激活插件或非官方激活服务器不仅不稳定还可能引入恶意字节码这在一个开发环境里是很危险的事。JRebel提供21天免费试用对于评估场景来说是够用的。团队采购IDE插件其实一个team license分摊下来成本不算高。如果你所在的公司已经买了JetBrains全家桶授权可以考虑从官方渠道了解JRebel和IDE的组合订阅是否有优惠。我的经验是开发工具的稳定性恰恰是开发效率的基石用不稳定的激活方案省下来那点钱会在排障时间里加倍赔回去。具体到激活步骤本地安装JRebel插件后选择“Connect to License Server”输入官方分配的激活服务器地址和邮箱验证码激活成功后在JRebel面板里可以看到License状态。整个流程两分钟没必要省。4.4 除了JRebel还有什么第三方热部署方案Arthas是一个阿里开源的Java诊断工具它不是严格意义上的开发期热部署工具但它的retransform命令可以在JVM运行中重新加载class文件这个能力在某些场景下比JRebel还实用。比如生产环境出了一个偶现问题不想重启服务可以把修复后的class文件上传到服务器用Arthas的retransform命令热替换掉出问题的类。它不是为开发期设计的但作为紧急止血手段非常好用。Spring Loaded是一个老掉牙的项目曾经是Spring官方提供的热重载方案现在基本停止维护了。它的思路和JRebel类似但对新版本Spring支持很差不建议新项目采用。HotSwapAgent是一个开源替代JRebel的方案基于DCEVM和HotSwap机制实现更强的热替换能力支持新增方法、修改类结构。它对JVM有特定要求需要安装增强版的JVMDCEVM有动手能力的团队可以尝试不过配置成本和稳定性风险都不低。5. 热部署的进阶场景与生产环境应用5.1 代码改了静态资源和模板文件不生效怎么办Spring Boot项目里静态资源和模板文件通常不需要触发重启。前端改了页面DevTools的LiveReload会帮你自动刷新浏览器后端不会重启。但有一个常见的问题Thymeleaf默认在生产模式下开启模板缓存模板文件改了之后页面内容不变。DevTools会自动修改Thymeleaf的配置把缓存关掉但如果没生效可以手动加上spring.thymeleaf.cachefalse如果项目里同时有Freemarker对应的配置是spring.freemarker.cachefalse关闭模板缓存只建议在开发和调试时使用生产环境一定要把缓存打开。模板缓存的本质是减少模板解析和渲染的开销生产环境下关闭缓存会导致页面渲染性能下降。改配置这种看似不起眼的操作在线上可能引发性能问题。5.2 监控和热部署的搭配Spring Boot Admin能做什么热搜词里有“Spring Boot Admin”和“实现监控都有哪些需求和功能”。把它和热部署放在一起说是因为监控是热部署的“仪表盘”。Spring Boot Admin是一个开源监控组件服务端收集各个Spring Boot应用通过Actuator暴露的监控指标在Web界面上展示。一个Spring Boot应用开启Actuator后会暴露很多端点比如/actuator/health查看健康状态、/actuator/info查看应用信息、/actuator/metrics查看JVM内存、线程、GC等指标。Spring Boot Admin把这些指标图形化方便查看。我自己的开发环境里用Spring Boot Admin配合DevTools能快速发现“重启之后内存有没有异常增长”“线程池是否被正确回收”这类问题。配置Actuator很简单dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependency然后在配置文件里暴露需要的端点management.endpoints.web.exposure.includehealth,info,metris如果项目里已经集成了Spring Boot Admin服务端客户端只需要添加admin-client依赖并配置服务端地址spring.boot.admin.client.urlhttp://localhost:8080热部署配合监控的意义在于你可以看到重启前后应用的健康状态变化如果重启导致某些Bean初始化失败监控页面上立刻就能看到健康检查从UP变成DOWN不用等浏览器请求报错才发现。5.3 生产环境的热更新Arthas实操记录Arthas在生产环境做紧急热更新的流程值得展开说说。假设线上有个订单状态判断逻辑写错了修复后的class文件已经编译好我们可以这样操作先下载Arthas并启动java -jar arthas-boot.jar然后选择要附加的Java进程进入Arthas交互界面。接着用retransform命令指定要替换的class文件路径retransform /tmp/OrderServiceImpl.class执行完成后Arthas会替换JVM里对应类的字节码。通过jad命令可以反编译验证当前运行的类是不是已经更新jad com.example.service.OrderServiceImpl这种热更新方式的优势是不需要重启进程不会导致正在处理的请求中断对系统可用性影响最小。但它只适用于“类内部逻辑修正”不适用于新增类、修改Spring Bean的依赖关系、修改配置文件。如果需要新增一个Bean还是要走发布流程。这套操作的注意事项是retransform不能修改类的结构不能新增方法、不能删字段、不能变更方法签名。如果改动超出这些范围retransform会报错这种情况下只能走正常发布或者灰度。另外替换后的字节码只在当前JVM实例中生效节点重启后失效所以它定位是“应急止血”不是常规发布工具。5.4 在IDEA社区版里做热部署的完整方案热搜词里有一条“IntelliJ IDEA社区版怎么用Spring Boot”这里专门说一下。IDEA社区版是免费的功能上和旗舰版相比缺少Spring框架的原生支持、缺少Spring Initializr向导但它完全不影响Spring Boot项目的创建、运行和调试。创建工程时可以手动添加Spring Boot的Maven依赖或者直接用start.spring.io网页生成项目再导入IDEA社区版。社区版做热部署的方案和旗舰版基本一致第一步在pom.xml中添加DevTools依赖。第二步打开Settings → Build, Execution, Deployment → Compiler勾选Build project automatically。第三步用Ctrl Shift Alt /唤出Registry勾选compiler.automake.allow.when.app.running。第四步通过正常方式启动Spring Boot应用。社区版同样可以安装JRebel插件。JetBrains插件市场对社区版和旗舰版是通用的JRebel插件在社区版里表现和旗舰版没有差异。社区版唯一的短板是缺少一些Spring相关的代码提示和向导但这些都不影响热部署本身。如果你的电脑性能一般在IDEA社区版里幅度调整代码时频繁重启会显得卡顿可以考虑调整DevTools的轮询间隔或者用触发文件模式控制重启时机。社区版没有旗舰版的“Spring Boot DevTools”高级设置面板但这些配置写在application.properties里是一样的效果。6. 常见问题与排查技巧实录6.1 改了代码没反应先查这四件事DevTools改完代码没触发重启90%的情况出在以下几个环节第一检查DevTools依赖是否生效。看启动日志里有没有Restarting Spring Boot application之类的记录。如果没有说明DevTools压根没参与运行。用Maven的spring-boot:run启动项目一般没问题但如果用IDE的Run按钮启动且依赖是后加的可能需要重新导入项目或者重启IDE。第二检查IDEA自动编译是否开启。很多人的“改了代码没反应”其实是IDEA根本没有编译出新class文件DevTools自然检测不到变化。这种情况在IDEA社区版里特别常见因为社区版的默认设置不会在应用运行时自动编译。确认Build project automatically和compiler.automake.allow.when.app.running都打开了。第三检查代码修改的内容是否在DevTools的监控范围内。源码文件、resources目录下的内容默认都在监控范围。如果改了src/test目录下的代码DevTools不会重启。改了外部依赖jar包的内容更不会触发重启。第四检查项目有没有配置exclude规则静态资源目录或者某些被排除的目录变更不会触发重启。这是特意的行为不是故障。按这个顺序排查大部分“没反应”的问题都能解决。6.2 DevTools启动报错和类加载冲突DevTools和某些依赖组合在一起会偶发类加载异常。最典型的是使用spring-boot-devtools时某些第三方库通过Thread.currentThread().getContextClassLoader()加载类而DevTools的重启类加载器和默认类加载器不同导致类找不到或者类型转换异常。解决方法有三种。最简单的是把出问题的库写在spring.devtools.restart.exclude里让它在稳定的类加载器里加载。复杂一点的是调整类加载策略让DevTools的类加载器委托给父加载器。再就是直接放弃DevTools改用JRebel或HotSwapAgent。我遇到的具体案例是项目里集成了一个短信SDK它内部用了TCCL加载类DevTools重启之后SDK初始化异常报ClassNotFoundException。最终是把SDK的包名加到restart的exclude规则里解决的。6.3 高版本JDK下的热部署兼容性排查JDK 17和JDK 21时代热部署方案都面临兼容性问题。DevTools本身不依赖特定JDK版本纯Java实现兼容性较好。但JRebel这类字节码增强工具对新JDK的适配通常需要时间。解决方案是确认工具版本。JRebel官网的发布说明里会明确标注支持哪些JDK版本。如果升级JDK后热替换失效先降级到工具官方支持的JDK版本等工具新版本发布后再升级。这个顺序千万别搞反工具先升级到官方支持新版JDK的版本再切JDK。另外JDK 21引入了虚拟线程很多Spring Boot应用开始用虚拟线程。字节码增强工具对虚拟线程的支持参差不齐。如果项目用了虚拟线程且有热部署需求需要在真实场景下验证热替换是否正常不要默认它没问题。6.4 生产维护老项目没有热部署机制的应急思路很多老项目跑在生产环境没有引入DevTools也没有Actuator端点代码有问题只能重启。这种情况下Arthas依然可以用但要注意另一个黑科技利用Java的-XX:AllowEnhancedHotSwap参数配合Debug模式做远程热替换。这个参数从JDK 9之后默认启用对增强化HotSwap的支持原生支持方法体替换。应急思路是本地用和线上一致的代码版本起一个Debug进程把线上Java进程的调试端口打开然后用IDE的远程Debug连接上去修改本地代码方法体后直接HotSwap到远程JVM。这种操作需要线上环境允许远程Debug安全风险极高一般只在测试环境应急用真正生产环境不建议开Remote Debug有被攻击的风险。6.5 一份常见问题速查表现象可能原因解决办法改代码后完全没反应DevTools未生效或IDE未自动编译确认依赖配置勾选Build project automatically和Registry选项重启频繁、卡顿静态资源或Mapper文件也触发了重启在exclude规则中排除静态目录调整additional-paths登录态/缓存频繁丢失自动重启导致Spring容器重建把状态移到Redis或数据库开发环境关闭安全拦截远程应用无法热更新安全限制或远程端口未开放确认remote.secret配置开发环境临时开放端口热替换报类转换异常DevTools类加载器与第三方SDK冲突将SDK包加入restart.excludeJRebel热替换不生效Module未激活或版本不兼容JDK在JRebel面板激活全部Module检查版本兼容模板修改不生效模板缓存开启开发环境设置spring.thymeleaf.cachefalseActuator端点不显示监控数据端点未暴露配置management.endpoints.web.exposure.include7. 我用了很久的一套组合拳最后分享一个我一直在用的热部署配置组合算是这些年摸索下来比较顺手的方案。主力开发环境用IDEA DevTools这是默认组合。日常改方法体、改业务逻辑保存后IDEA自动编译DevTools两秒内完成重启浏览器配合LiveReload自动刷新页面。对于那种只是微调一下方法内部逻辑的改动偶尔叠加IDE Debug模式的原生HotSwap连DevTools的重启都免了。当项目启动时间超过15秒时我会直接切到JRebel——启动时间一旦超过这个阈值DevTools重启一次的综合感知耗时就会变得明显而在JRebel下改一个方法体的耗时几乎无感。JRebel不需要重启改Controller、Service、Mapper都能直接热替换。用JRebel之后DevTools会被我彻底关掉避免两者的类加载器冲突。线上应急用Arthas。生产环境出了紧急问题修复后先用Arthas的retransform做热修补同时走紧急发布流程。Arthas不常上场但每次上场都价值巨大。这套组合里踩过的坑、总结的经验上面基本都写到了。热部署这个事情投入成本极低收益却立竿见影。配置一次长期受益强烈建议每个Spring Boot开发者都把它配起来。不要等到每天重启几十次、时间都被白白耗掉之后再后悔现在就动手把热部署搞起来开发体验立刻不一样。