方案 1:开发环境首选(JRebel + Tomcat)
JRebel 是业界最成熟的热部署工具,能直接替换单个 class/配置文件,无需重启应用/上下文,生效时间毫秒级,是开发环境的最优解。
1.1 前置条件
- JDK 8+
- Tomcat 8.5+/9.x/10.x
- 开发工具(IDEA/Eclipse,以 IDEA 为例)
1.2 落地步骤
步骤 1:安装 JRebel 插件(IDEA)
- 打开 IDEA → Settings → Plugins → 搜索「JRebel and XRebel」→ 安装并重启 IDEA;
- 破解/激活(个人开发可使用免费试用版,或通过官方授权)。
步骤 2:配置 Tomcat + JRebel
- 打开 IDEA 的「Run/Debug Configurations」→ 选择 Tomcat 配置 → 切换到「JRebel」标签;
- 勾选你的项目(如
myapp),开启「JRebel for WebApps」; - 关键配置:勾选「Auto-reload in background」(后台自动重载)。
步骤 3:配置 Tomcat 兼容(可选)
修改 Tomcat 的 conf/context.xml,关闭原生重载(避免冲突):
<Context
reloadable="false" <!-- 必须关闭Tomcat原生重载 -->
antiResourceLocking="true" <!-- 解决Windows文件锁定 -->
>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>
步骤 4:验证效果
- 点击 IDEA 右上角「Run with JRebel」启动 Tomcat;
- 修改项目中任意 class 文件(如
UserService.java)→ 按Ctrl+S保存; - 无需等待,直接访问接口,class 变更已生效(日志会输出
JRebel: Reloading class 'com.example.UserService')。
1.3 核心优势
- 支持单个 class/配置文件/静态资源 热替换,无需重启应用;
- 兼容 Spring/Spring Boot/MyBatis 等主流框架;
- 开发效率提升 80%+,毫秒级生效。
方案 2:开源替代(Spring Loaded + Tomcat)
如果不想用商业工具,可使用 Spring 官方的开源热加载工具 Spring Loaded,实现接近 JRebel 的效果(仅支持 class 替换,配置文件需手动刷新)。
2.1 落地步骤
步骤 1:引入 Spring Loaded 依赖
下载 springloaded-1.2.8.RELEASE.jar(官方下载地址),放到 Tomcat 的 bin 目录下。
步骤 2:修改 Tomcat 启动脚本
- Windows:修改
bin/catalina.bat,在开头添加:set JAVA_OPTS=-javaagent:%CATALINA_HOME%\bin\springloaded-1.2.8.RELEASE.jar -noverify - Linux/Mac:修改
bin/catalina.sh,在开头添加:JAVA_OPTS="-javaagent:$CATALINA_HOME/bin/springloaded-1.2.8.RELEASE.jar -noverify"
步骤 3:配置项目(Maven/Gradle)
Maven 项目需在 pom.xml 中添加编译插件(确保 class 文件编译后自动输出到 Tomcat 应用目录):
<build>
<plugins>
<!-- 自动编译并复制class到Tomcat目录 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
<outputDirectory>${tomcat.home}/webapps/myapp/WEB-INF/classes</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
步骤 4:验证效果
- 启动 Tomcat(
bin/startup.bat/startup.sh); - 修改
UserService.java→ 执行mvn compile(或 IDEA 自动编译); - 访问接口,class 变更已生效(无应用重启日志)。
2.2 注意事项
- 仅支持 class 方法体修改(新增/删除字段/方法需重启);
- 不支持配置文件热加载(需搭配
spring-boot-devtools补充); - 兼容 Tomcat 8+,JDK 8/11 适配良好。
方案 3:生产环境轻量方案(自定义类加载器 + 接口重载)
生产环境不建议直接热替换 class(易引发类加载泄漏),推荐「自定义类加载器 + 接口代理」方案,实现无感知更新核心业务逻辑。
3.1 核心思路
- 将需要热更新的业务逻辑抽离为接口(如
BusinessService); - 自定义 Tomcat 类加载器,加载接口的实现类;
- 提供「重载接口」,触发重新加载实现类的 class 文件,替换代理对象。
3.2 落地代码
步骤 1:定义业务接口和实现类
// 核心业务接口
public interface BusinessService {
String doBusiness(String param);
}
// 初始实现类(可热更新)
public class BusinessServiceImpl implements BusinessService {
@Override
public String doBusiness(String param) {
return "旧逻辑:" + param;
}
}
步骤 2:自定义类加载器
public class HotSwapClassLoader extends ClassLoader {
// 加载指定路径的class文件
public Class<?> loadClassFromFile(String classPath, String className) throws Exception {
File file = new File(classPath + "/" + className.replace(".", "/") + ".class");
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
byte[] classBytes = bos.toByteArray();
fis.close();
bos.close();
// 自定义加载class(不使用双亲委派)
return defineClass(className, classBytes, 0, classBytes.length);
}
}
步骤 3:实现热重载接口
@RestController
@RequestMapping("/hotswap")
public class HotSwapController {
// 代理对象,用于替换实现类
private volatile BusinessService businessService = new BusinessServiceImpl();
// 业务接口
@GetMapping("/business")
public String business(String param) {
return businessService.doBusiness(param);
}
// 热重载接口(生产环境需加权限校验)
@PostMapping("/reload")
public String reload() {
try {
// 自定义类加载器加载新的class文件
HotSwapClassLoader classLoader = new HotSwapClassLoader();
Class<?> newClass = classLoader.loadClassFromFile(
"/tomcat/webapps/myapp/WEB-INF/classes", // class文件路径
"com.example.BusinessServiceImpl" // 实现类全限定名
);
// 替换代理对象
businessService = (BusinessService) newClass.newInstance();
return "重载成功";
} catch (Exception e) {
return "重载失败:" + e.getMessage();
}
}
}
步骤 4:验证生产环境热更新
- 启动 Tomcat,访问
http://localhost:8080/myapp/hotswap/business?param=test,返回「旧逻辑:test」; - 修改
BusinessServiceImpl的代码(如返回「新逻辑:test」),编译后替换 Tomcat 应用目录下的BusinessServiceImpl.class; - 调用重载接口:
POST http://localhost:8080/myapp/hotswap/reload; - 再次访问业务接口,返回「新逻辑:test」(无应用重启,仅替换单个类)。
3.3 生产环境注意事项
- 仅对无状态的业务类生效(有状态类需处理数据一致性);
- 重载接口需添加权限校验(如 Token/IP 白名单),避免恶意调用;
- 定期监控 Metaspace 内存(类加载器创建过多可能导致溢出)。
总结
- 开发环境:优先用 JRebel,一键配置即可实现单个 class/配置文件热替换,效率最高;
- 开源替代:Spring Loaded 免费,支持基础 class 热替换(仅方法体修改),适合小型项目;
- 生产环境:采用「自定义类加载器 + 接口代理」方案,仅热更新核心业务类,避免全应用重启,安全性可控。
核心关键点:Tomcat 原生热部署是「应用重启」,而真正的单个 class 替换需借助 类加载器改造(JRebel/Spring Loaded/自定义加载器)突破 Java 原生限制。
注意:本文归作者所有,未经作者允许,不得转载