1 类加载原理

Java类的加载过程主要分为三个步骤,加载、链接、初始化,其中将类加载到JVM中的工作由类加载器完成。在加载阶段,类加载器可以从不同的数据源(jar文件、class文件、网络文件)读取 Java 字节代码,并转换成 java.lang.Class类的一个实例。
在Java中,主要提供有四种类加载器,引导类加载器(BootStrapClassLoader)、扩展类加载器(ExtClassLoader)、应用类加载器(AppClassLoader) 以及用户自定义的 ClassLoader,这四种类加载器有着明显的层级关系(由顶至下)(引导类加载器->扩展类加载器->应用类加载器->自定义加载器),其中引导类加载器用来加载Java的核心库,比如加载 jre/lib 下面的 jar 文件,扩展类加载器负责加载我们放到 jre/lib/ext/ 目录下面的 jar 包,而应用类加载器则加载系统变量classpath路径下 的内容,当然,我们也可以实现自定义的类加载器,自己控制和管理类的加载过程。
另外,这四种类加载器在加载类的时候会遵循一个称作“双亲委派”的准则,在加载类的时候,会首先委派其父加载器进行加载,如果已经加载则直接返回该类的引用,这是一个递归的过程。如果到最顶层也没有加载到指定类,那么会自顶向下挨个尝试加载,直到用户自定义类加载器,如果还不能成功,就会抛出异常。

2 类的热加载基本实现

热加载指的是,在不停止正在运行的系统的情况下进行类的替换,前面我们知道了类的加载由类加载器完成。热加载是类加载常见的应用,比如Tomcat中jsp的热替换。下面我们自定义类加载器实现简单的类的热加载。

2.1 自定义类加载器

对于类加载器,有几个重要的方法:
loadClass:加载类的入口方法,其中实现遵循了双亲委派机制,该方法返回Class实例;
findClass:loadClass方法中,如果其父类加载器无法加载指定类,则调用自身的findClass方法完成加载,该方法返回Class实例;
defineClass:接收以字节数组表示的类字节码,并把它转换成 Class 实例;

public class MyClassLoader extends ClassLoader{private String classpath;public MyClassLoader(String classpath){this.classpath = classpath;}@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {byte[] classdata = loadClassData(name);return this.defineClass(name, classdata, 0, classdata.length);}private byte[] loadClassData(String name) {try {name = name.replace(".", "//");String path = classpath + name + ".class";File file = new File(path);FileInputStream is = new FileInputStream(file);ByteArrayOutputStream baos = new ByteArrayOutputStream();int b = 0;while ((b = is.read()) != -1) {baos.write(b);}is.close();return baos.toByteArray();} catch (Exception e) {e.printStackTrace();}return null;}
}

2.2 热加载实现

我们首先试着自定义一个测试接口,并由自定义类加载器完成接口实现类的热替换:

public interface HelloService {void sayHello();}

热替换实现,这里依赖于接口,不依赖于具体:

public class Main {private static final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);public static void main(String[] args) {classLoaderTest();}public static void classLoaderTest(){Class<?> clazz = null;try {MyClassLoader myClassLoader = new MyClassLoader("D:/Workspaces/IdeaProjects/classloader-java-class/out/production/classloader-java-class/");clazz = myClassLoader.loadClass("gdou.laixiaoming.HelloServiceImpl");System.out.println("加载HelloService实现类成功,由"+clazz.getClassLoader() + "加载");HelloService helloService = (HelloService)clazz.getConstructor(new Class[]{}).newInstance(new Object[]{});helloService.sayHello();} catch (Exception e) {e.printStackTrace();}scheduledExecutorService.schedule(() -> {classLoaderTest();}, 1 , TimeUnit.SECONDS);}
}

另外再新建一个Java项目,实现前面的测试接口,主要用于测试实现类的自动编译,拿到得自动生成的class文件:

public class HelloServiceImpl implements HelloService {@Overridepublic void sayHello() {System.out.println("Hello,ClassLoader!");}
}

这里要注意一下,IDEA默认并没有打开自动构建功能,这里需要手动开启,路径为:

运行main方法,修改HelloServiceImpl实现,可以看到,控制台输出为修改后最新的内容。

参考:Java 类的热替换 —— 概念、设计与实现

Java类的热加载原理与实现相关推荐

  1. java编写hot_类的热加载(Hot Deployment)的简单例子

    应用服务器一般都支持热部署(Hot Deployment),更新代码时把新编译的确类 替换旧的就行,后面的程序就执行新类中的代码.这也是由各种应用服务器的独 有的类加载器层次实现的.那如何在我们的程序 ...

  2. webpack 热加载原理探索

    前言 在使用 dora 作为本地 server 开发一个 React 组件的时候,默认使用了 hmr 插件.每次修改代码后页面直接更新,不需要手动 F5 ,感觉非常惊艳,这体验一旦用上后再也回不去了. ...

  3. java类二次加载_深入理解java之类加载器

    一.类与类加载器 类加载器:实现加载阶段的第一步,通过一个类的全限定名来将这个类的二进制字节流加载进jvm. 类与类加载器:任意一个类唯一性都是由它本身和加载它的类加载器确定,两个类是否相等在它们是由 ...

  4. java类是如何加载的?不知道classLoader和双亲委派,不是一个合格的程序员

    目录 详细图送上 类加载器子系统 类的加载过程 加载(loading)阶段 链接(linking) 验证(Verify) 准备(Prepare) 解析(Resolve) 初始化(Initializat ...

  5. php热加载原理,什么是热更新?

    热更新是指软件不通过运营商店的软件版本更新审核,直接通过应用自行下载的软件数据更新的行为.简单来说,就是在用户下载安装APP之后,打开App时遇到的即时更新.热更新是一种各大手游等众多App常用的更新 ...

  6. 原来热加载如此简单,手动写一个 Java 热加载吧

    1. 什么是热加载 热加载是指可以在不重启服务的情况下让更改的代码生效,热加载可以显著的提升开发以及调试的效率,它是基于 Java 的类加载器实现的,但是由于热加载的不安全性,一般不会用于正式的生产环 ...

  7. java热加载_java--热加载

    1. 什么是热加载 热加载是指可以在不重启服务的情况下让更改的代码生效,热加载可以显著的提升开发以及调试的效率,它是基于 Java 的类加载器实现的,但是由于热加载的不安全性,一般不会用于正式的生产环 ...

  8. java 类编译_Java类编译、加载、和执行机制

    Java类编译.加载.和执行机制 标签: java 类加载 类编译 类执行 机制 0.前言 个人认为,对于JVM的理解,主要是两大方面内容: Java类的编译.加载和执行. JVM的内存管理和垃圾回收 ...

  9. 查看类的实现类mac_自定义类加载器实现热加载

    一.实现的需求 当一个java被修改后,系统无需重启,替换的类立即生效,这里以Work.java为例 二.实现的思路 1)难点分析 当项目在执行的时候,我们修改了Work.java,这个类的class ...

最新文章

  1. 浅析网站建设之初应该从哪些方面进行考虑?
  2. SpringBoot常见功能特性分析
  3. CSS3如何实现0.5边框
  4. MySQL 基础 ———— 存储过程与函数
  5. initrd的启动过程
  6. php 子类重新定义父类的变量_PHP设计模式 ——(抽象工厂模式)
  7. Silverlight5 RC调用Win32API
  8. “CEPH浅析”系列之六——CEPH与OPENSTACK
  9. 全国大学生创新创业比赛-----采油厂绩效考核系统的设计与开发
  10. poi导出excel设置对应格式
  11. VBA 实现批量word 转 pdf
  12. 数据包络分析法(DEA)_2
  13. 台风怎么看内存颗粒_内存应该怎么选?看完你就知道了。影驰 星曜 DDR4-3000 8G 内存测评(RGB真的强)...
  14. MFC控件响应鼠标中键OnMouseWheel
  15. 如何将PPT输出为高精度的图片
  16. “一见杨过误终生”,《神雕侠侣》2014年 超清1080P未删节版52集全
  17. php搜索银行所在支行,如何查询怎么查建设银行所属支行?
  18. 【这很AI】谷歌再推AI应用“名画匹配”:与博物馆7万幅历史名画匹配,结果可能是梵高
  19. 试题 历届试题 对局匹配
  20. 步进电机基本原理及驱动方式详解

热门文章

  1. 现代C++改变了什么
  2. 2D游戏入门——小狐狸系列(二)处理素材
  3. 利用ArcGIS做一张“三调“土地利用现状图(附三调符号库下载)
  4. babel ES6 转换 ES5 实现原理
  5. 基于服务器的p2p协议实现,基于P2P协议的文件服务器技术.PDF
  6. 微商引流精准客源,全自动黑科技软件!
  7. CSS圆角 border-radius椭圆 / 正斜杠是什么?
  8. i219v微星 驱动_Windows Server 2019 安装 Intel I219V 网卡驱动
  9. 虚假谣言,新闻的检测与分析论文
  10. 杂谈---LZ的编程之路以及十点建议