在日常开发过程中,最浪费时间的事情莫过于修改了代码之后还需要在重新编译项目甚至重新启动项目之后代码才能够生效。JRebel 插件就能够很好地解决这个问题。
以 IntelliJ IDEA 为例,在修改完代码之后,需要点击 Build Porject 按钮(快捷键为 Ctrl+F9),或者点击 update "xxx" application 按钮(快捷键为 Ctrl+F10)之后才能重新加载代码,然后修改后的代码才开始生效。
那有没有一种方法,可以不需要额外的操作,又可以在很短的时间内自动加载修改后的代码并使其生效呢?
通常情况下,项目的代码在被 IDEA 编译之后,其编译之后的源码会被存放到类似于 {项目所在的路径}/target/classes 的目录中,但是项目在运行过程中使用的并不是这个路径中的代码。以下面的文件结构为例,IDEA 会将编译之后的代码存放到 DemoProject/target/classes 目录中,而开发环境下项目运行时所使用的代码则是 DemoProject/target/DemoProject/WEB-INF/classes 中的代码。
//使用了 Maven 的 web 应用
DemoProject
|--src //存放项目的源代码
|--target
| |--classes //存放编译之后的源代码
| 、--DemoProject //项目运行时的目录
| 、--WEB-INF
| |--classes //存放项目运行时所需的源代码
| 、--web.xml
、pom.xml
JRebel 所做的,就是在运行 DemoProject 的时候,用 DemoProject/target/classes 目录中的源代码来替代 DemoProject/target/DemoProject/WEB-INF/classes 目录中的源代码,也就是说此时运行项目所用的代码不是 DemoProject/target/DemoProject/WEB-INF/classes 中的代码,而是 DemoProject/target/classes 中的代码,然后在项目开发过程中, 一旦 JRebel 检测到 DemoProject/target/classes 目录的代码或文件发生了变化,就会重新加载修改之后的代码,再然后被修改的代码就开始生效了,这样有一个好处,只要 IDEA 一编译完项目(更准确的说是将项目的 .class 编译成 .java,并将 .java 文件放到 xxx/target/classes 目录中),项目中被修改的代码就可以立马生效,而不用像平常那样还要更新 DemoProject/target/DemoProject/WEB-INF/classes 里的代码。同样的道理, Build Porject 与 update "xxx" application 将会更新 xxx/target/classes 目录中的代码,JRebel 一旦检测到这个目录中的内容发生了改变,就会重新加载代码,最后,被修改的代码就生效了。
自动更新代码
能让 JRebel 自动加载代码的方式主要有两种:
设置 On frame deactivation
On frame deactivation 用来设置当鼠标的焦点离开代码操作区域,或者离开 IDEA 窗口时所要执行的操作。当把 On frame deactivation 的操作设置为 Update resources 或者设置为 Update classes and resources 时,每当鼠标的焦点离开代码操作区域或者离开 IDEA 窗口时,IDEA 将会自动编译代码(或者更新静态资源),这时就会触发 JRebel 去重新加载代码,从而让被修改的代码立即生效。
设置 build automatically
在使用 IDEA 的时候,我们会发现我们根本就不需要手动地去保存代码,因为 IDEA 会自动地帮我们保存代码。同时 IDEA 还有一个功能,它可以让 IDEA 在自动保存代码的同时自动地去编译代码,这个行为同样会触发 JRebel 来重新加载代码,从而让被修改的代码立即生效,这个功能就是 Build project automatically ,开启这个功能的方式为:Settings -> Build, Execution, Deployment -> Compiler -> 勾选 Build project automatically 选项,如果你有注意看的话,你会发现这个选项的后面有一行说明:only works while not running / debugging ,也就是说当项目在运行时这个功能是不起作用的。
但是可以通过修改 IDEA 注册表的方式来解决 Build project automatically 无法在项目运行时使用的问题,解决的方式为:输入快捷键 Ctrl+Shift+A ,在 Actions 中搜索 registry,然后给 compiler.automake.allow.when.app.running 打上勾,这样子就可以在项目运行的时候自动地编译项目。
IDEA 在默认情况下,自动保存的时间为 10s ,也就是说每次修改完代码之后,需要等待 10s IDEA 才会自动地保存代码,这也就意味着,每次修改完代码之后需要至少等待 10s 之后才会触发 JRebel 来加载修改之后的代码。如果想缩短等待的时间的话,可以修改 IDEA 自动保存的等待时长,修改的方式为:Settings -> Appearance & Behavior -> System Settings -> Save files automatically if application is idle for x sec ,假设将其设置为 1s 的话,则将会在修改代码差不多 1~2s 之后就会触发 JRebel 来加载修改后的代码,让修改后的代码即时生效,以达到近乎代码一变动就立即生效的效果。
最后,希望这篇文章能带给你点启发,Have Fun!