写在最前面

作为 JVM 语言开发者,自然都听说过大名鼎鼎的 JRebel 吧。

没听说过? 好吧,编不下去了,直接进入主题吧

实际项目开发中的热部署需求

没有热部署: 修改代码->重新编译->重新部署整个项目 (通常会花费5秒以上)->继续测试

有热部署: 修改代码->重新编译->通过调试器替换变化的字节码文件 ()->继续测试

热部署为什么需要插件

其实原版 JDK 就可以实现热部署,只是功能非常地局限,可以实现方法内代码的在线更新,但不能实现新增方法和删除方法。

于是才就有了热部署插件。

JRebel 和 HotswapAgent 的区别

  • JRebel 更加成熟,支持更多框架和插件
  • JRebel 不开源,并且要价不菲!
  • JRebel 在热加载时会修改所有的字节码文件,因此必须要安装一个 IDE 插件才能使调试功能不受影响
  • HotswapAgent 只需要很简单的配置即可使用(甚至不需要写任何配置文件)
  • HtoswapAgent 是基于 DCEVM (一款魔改增强的 JVM) 实现的,IDE 仍然可以使用 JDK 原生的 Debug 方式, 因此不需要安装额外的插件
  • HotswapAgent 是开源的!!!!

前置准备 (准备一个支持方法热加载的 JVM)

DCEVM

Dynamic Code Evolution VM (动态代码演化虚拟机) 项目地址

是一款开源项目,旨在让 JVM 能够对方法新增和删除实现热加载

  1. 在该项目的 release 页面找到对应 JDK 版本的 Installer

  2. 使用 Installer 安装 DCEVM 到你的 JDK 环境中

  3. 通过在 VM Options 中加上 -XXaltjvm=dcevm 即可以 DCEVM 启动

问题是:DCEVM 支持的是 OpenJDK 而非 Oracle JDK !!!

看到这里你可能想说:那我还得找个 DCEVM 支持的 OpenJDK 比如 openjdk-8u181, 然后下载 8u181 版本对应的 Installer, 可是你说的 openjdk-8u181 在哪儿呢,难道要我去自己下 openjdk 代码然后自己编译?

所以推荐的办法是直接使用 TravaOpenJDK

TravaOpenJDK

TravaOpenJDK 是为开发者量身定制的 OpenJDK,他将 DCEVM 作为了它默认的 JVM,让 DCEVM 能够开箱即用。

说了半天,估计汝也不耐烦了,直接给链接:

注意:TravaOpenJDK 已经把 DCEVM 作为了它默认的 JVM,无需添加 -XXaltjvm=dcevm 参数

使用 HotswapAgent

这时你可能要问:我已经用上了 DCEVM 了,方法新增/删除的热加载已经能实现了,那我还需要什么?

确实是这样,新增/删除的方法能实现热加载已经很香了。

试问:如果新增的方法上面有一个 @RequestMapping 注解的情况呢?那么谁去通知 Spring 框架去重新扫描这个方法上的注解呢?

答案就是 HotswapAgent

TravaJDK 11 已经整合了 HotswapAgent

使用方法:

  1. VM Options 中添加:

    • -XX:HotswapAgent=fatjar 使用内置的完整版 HotswapAgent (提供框架支持)

    • -XX:HotswapAgent=core 使用内置精简版 HotswapAgent (不支持框架)

    • -XX:HotswapAgent=external -javaagent:<path>/hotswap-agent.jar 使用外置 hotswap-agent.jar

    • image-20210122222606

  2. 设置 On 'Update' actionUpdate classes and resources

    • image-20210122223437
  3. 以 Debug 方式启动项目

    • 应该能看到控制台打印出一些 HotswapAgent 相关的日志,例如:

      HOTSWAP AGENT: 22:25:07.654 INFO (org.hotswap.agent.config.PluginRegistry) - Plugin 'org.hotswap.agent.plugin.spring.SpringPlugin' initialized in ClassLoader '[email protected]'.
      HOTSWAP AGENT: 22:25:07.655 INFO (org.hotswap.agent.plugin.spring.SpringPlugin) - Spring plugin initialized - Spring core version '5.3.3'
      
  4. 修改代码之后通过 Update 进行热加载

    • image-20210122223717
  5. 设置 Idea 编译后自动热加载 (可选)

    • image-20210122224913

TravaJDK 8 不含内置 HotswapAgent

只能通过 -javaagent:<path>/hotswap-agent.jar 指定外置 HotswapAgent。

hotswap-agent.jar

使用效果