项目每次启动都要一分多钟,改一行代码就要重启很难受?推荐一款提高工作效率的热加载JVM插件:JRebel。
JRebel笔者也用很长一段时间了,这货确实帮我省了不少时间,所以才强烈推荐大家使用。
这是一款实现热加载的JVM插件,官方也为IDEA提供了JRebel IDEA 插件,使用和安装也都非常简单,动动手指就能找到很多安装教程。
推荐参考这篇文章的破解教程,简单可用:《JRebel破解最简单的使用》,链接:https://juejin.cn/post/6844903950781677582。
安装插件后,在idea的左侧工具栏可以看到jrebel选项,点开后勾选需要使用jrebel插件的应用,如下图所示。
勾选后,当前项目的DEBUG一栏会出现有jrebel logo的debug按钮,如下图所示。
当我们修改某个类后,如果想要即时生效,可在当前类的编辑窗口中右键,选择Compile And Reload File,如下图所示。
官网强调JRebel是实现热加载的JVM插件,那热加载与热部署有何不同呢?
- 热部署:jvm进程不重启,重新加载整个web应用;
- 热加载:运行时重新加载类。
我们熟知的Tomcat就是使用热部署实现不重启JVM支持多web应用部署以及重新部署,对web应用而言是已经重启了,而JRebel是使用热加载实现不重启应用也能使修改生效。
如果你做过Android应用开发,那么你应该还熟悉一个词:热修复。
17年笔者在做Android应用开发的时候热修复这项技术就非常火,如热门代表:手Q空间超级补丁技术、微信Tinker、阿里百川HotFix。手Q空间超级补丁技术、微信Tinker在实现原理上都是通过在应用启动时将新的dex替换旧的dex实现(替换class),需要应用重启才生效,阿里百川推出的热修复HotFix则不同于前两者,下拉补丁后无需重启应用就能立即生效。
为什么Android应用开发领域的热修复可以那么火?不同于WEB应用更新,WEB应用更新用户是被动接受,而Android版本更新需要用户主动去更新。而使用热修复可以实现让用户被动接受更新,在应用重启时神不知鬼不觉的动态修复bug,优化用户体验,同时也就减少APP的卸载率。
随着后端项目不断臃肿,导致依赖的很多框架初始耗时越来越长,热加载开始被用于提升后端开发效率,被用到后端开发调试上。当然,也有使用热加载实现修复线上bug的,但在微服务容器化部署时代,已经体现不出这样做的价值了。
你可能会说,现在微服务不会很臃肿,本地调试重启也就几秒钟的事情,使用它效率也不明显。但如果重启需要重新登录或者说需要做一些初始化工作就不好说了。
尽管热加载很实用,它可以帮我们省去大部分改写代码的重启时间。但也并不是所有场景都能使用热加载替代重启。
如果我们改动的是Mybatis的SQL、Spring的注解或配置类等,我们依然需要重启应用。原因很好理解,我们就以依赖Spring和Mybatis框架的应用为例说明。
首先是修改Spring配置类或者一些类上的注解重新编译热加载后发现修改并未生效,这是因为Spring只在容器启动时应用配置类、扫描Bean类时读取类上的注解等。
其次是Mybatis,无论我们修改的是注解上的Sql还是xml文件中的Sql都不会生效,因为Mybatis初始化时就需要读取xml文件中的sql或者接口方法上注解的sql来为接口生成代理类,后续不会再用到注解或xml文件,因此动态修改不会生效。
说到Mybatis,笔者找到一款IDEA插件能够解决修改sql需要重启应用的问题:【jrebel-mybatisplus-idea-plugin】https://github.com/SweetInk/jrebel-mybatisplus。
关于JRebel的实现原理笔者也不了解,因为找不到更多资料,JRebel也不开源。如果让我实现一个简单的热加载,我也有一个简单的思路,通过已知的Java Agent和IDEA插件知识,可以通过动态重新加载类的方式完成简单的方法代码改写,也会有应用场景,如修复调试时发现的空指针异常、不涉及其它框架的业务逻辑错误、组件逻辑错误等,避免过多的应用重启。
本文转载自微信公众号「Java艺术」,可以通过以下二维码关注。转载本文请联系Java艺术公众号。