「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战」
引言
在项目开发中,每次修改文件就需要重启一次代码,这样太浪费时间了,所以在IDEA中使用JRebel插件实现项目🔥热部署,可自动热部署,无需重启项目。虽然一直清楚热部署是打破双亲委派来实现的,但是一直没有手写过热部署代码,今天写一次。😁
双亲委派机制
了解热部署之前,首先需要知道什么是双亲委派,在IDE中写的代码最终经过编译器会形成.class
文件,由classLoader
加载到JVM中执行。
JVM中提供了三层的ClassLoader:
- Bootstrap classLoader:主要负责加载核心的类库(java.lang.*等),构造ExtClassLoader和APPClassLoader。
- ExtClassLoader:主要负责加载jre/lib/ext目录下的一些扩展的jar。
- AppClassLoader:主要负责加载应用程序的主函数类
加载过程图如下:
实现热部署思路
一个类一旦被JVM加载过,就不会再次被加载。想实现热部署,就需要在.class
文件修改后,由classLoader
重新加载修改的.class
文件。对.class
文件做监听,一旦文件修改,则重新加载类。
在此实现中用一个Map模拟JVM已经加载过的.class
文件,当监听到文件内容修改之后,移除Map中旧的.class
文件,将新的.class
文件加载并存放至Map中,调用init方法,执行初始化动作,模拟.class
文件已经加载到JVM虚拟机中。
代码实现
pom文件
1 | xml复制代码<?xml version="1.0" encoding="UTF-8"?> |
IApplication接口
定义IApplication接口,所有监听的类都实现自这个接口。
1 | java复制代码public interface IApplication { |
TestApplication1
监听加载的类
1 | java复制代码public class TestApplication1 implements IApplication { |
IClassLoader
类加载器,实现通过包扫描类的功能
1 | java复制代码public interface IClassLoader { |
SimpleJarLoader
1 | java复制代码import com.hanhang.inter.IClassLoader; |
AppConfigList配置类
1 | java复制代码@Data |
GlobalSetting 全局配置类
1 | java复制代码public class GlobalSetting { |
application.xml配置
通过xml配置加后面的解析,确定监听那个class文件。
1 | xml复制代码<apps> |
JarFileChangeListener 监听器
1 | java复制代码public class JarFileChangeListener implements FileListener { |
AppConfigManager
此类为config的管理类,用于加载配置。
1 | java复制代码import com.hanhang.config.AppConfigList; |
ApplicationManager
此类管理已经在Map中加载的类,并且添加监听器,实现class文件修改后的监听重新加载工作。
1 | java复制代码import com.hanhang.config.AppConfigList; |
MainTest
测试类,创建一个线程,让程序一直监听文件修改。
1 | java复制代码public static void main(String[] args){ |
代码演示
程序启动后,控制台输出
将TestApplication1
的init方法修改为:
1 | java复制代码@Override |
重新build项目,控制台输出如下:
此时,TestApplication1
已经重新加载。
总结
以上就是我实现🔥热部署的代码,github源码地址:github.com/hanhang6/ho…
如果觉得我写的有问题,评论区里可以留言。
本文转载自: 掘金