图解classloader加载class的流程及自定义ClassLoader

【工作小札】自定义classloader实现热加载jar 我们这里定义,需要加载的jar的结构和maven打包出来的jar一致。我们编写一个测试jar如下:执行package命令获取jar包:sheep-web-demo-custom-classloader-jar-1.0-SNAPSHOT.jar/*** 自定义jar/*** jar文件/*** 源路径} } 阅读详情

http://longdick.iteye.com/blog/442213


java应用环境中不同的class分别由不同的ClassLoader负责加载。
一个jvm中默认的classloader有Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader,分别各司其职:


  • Bootstrap ClassLoader      负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等
  • Extension ClassLoader       负责加载java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和class
  • App ClassLoader           负责加载当前java应用的classpath中的所有类。

 

其中Bootstrap ClassLoader是JVM级别的,由C++撰写;Extension ClassLoader、App ClassLoader都是java类,都继承自URLClassLoader超类。
Bootstrap ClassLoader由JVM启动,然后初始化sun.misc.Launcher ,sun.misc.Launcher初始化Extension ClassLoader、App ClassLoader。

下图是ClassLoader的加载类流程图,以加载一个类的过程类示例说明整个ClassLoader的过程。

 



 Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader三者的关系如下:

Bootstrap ClassLoader是Extension ClassLoader的parent,Extension ClassLoader是App ClassLoader的parent。

但是这并不是继承关系,只是语义上的定义,基本上,每一个ClassLoader实现,都有一个Parent ClassLoader。

 

可以通过ClassLoader的getParent方法得到当前ClassLoader的parent。Bootstrap ClassLoader比较特殊,因为它不是java class所以Extension ClassLoader的getParent方法返回的是NULL。

 

了解了ClassLoader的原理和流程以后,我们可以试试自定义ClassLoader。

 

关于自定义ClassLoader:

 

由于一些特殊的需求,我们可能需要定制ClassLoader的加载行为,这时候就需要自定义ClassLoader了.

自定义ClassLoader需要继承ClassLoader抽象类,重写findClass方法,这个方法定义了ClassLoader查找class的方式。

主要可以扩展的方法有:

findClass          定义查找Class的方式

defineClass       将类文件字节码加载为jvm中的class

findResource    定义查找资源的方式

 

如果嫌麻烦的话,我们可以直接使用或继承已有的ClassLoader实现,比如

 

  • java.net.URLClassLoader
  • java.security.SecureClassLoader
  • java.rmi.server.RMIClassLoader
  • sun.applet.AppletClassLoader

Extension ClassLoader 和 App ClassLoader都是java.net.URLClassLoader的子类。

这个是URLClassLoader的构造方法:

 

public URLClassLoader(URL[] urls, ClassLoader parent)

public URLClassLoader(URL[] urls)

 

urls参数是需要加载的ClassPath url数组,可以指定parent ClassLoader,不指定的话默认以当前调用类的ClassLoader为parent。

 

代码示例:

 

Java代码   收藏代码
  1. ClassLoader classLoader = new URLClassLoader(urls);  
  2. Thread.currentThread().setContextClassLoader(classLoader);  
  3. Class clazz=classLoader.loadClass("com.company.MyClass");//使用loadClass方法加载class,这个class是在urls参数指定的classpath下边。  
  4.   
  5. Method taskMethod = clazz.getMethod("doTask", String.class, String.class);//然后我们就可以用反射做些事情了  
  6. taskMethod.invoke(clazz.newInstance(),"hello","world");  

 

 

由于classloader 加载类用的是全盘负责委托机制。所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入。

所以,当我们自定义的classloader加载成功了com.company.MyClass以后,MyClass里所有依赖的class都由这个classLoader来加载完成。

 

自定义ClassLoader在某些应用场景还是比较适用,特别是需要灵活地动态加载class的时候。

下面这篇文章列出了其中一种自定义ClassLoader的应用场景,有兴趣的同学可以参考下:


深入理解SpringBoot加载FatJar原理 本文将从源码角度介绍SpringBoot是如何自定义ClassLoader去加载FatJar的,以及FatJar又是如何读取jar里面嵌套jar中的类,中间会涉及到一些ClassLoader的知识。 阅读详情

相关推荐

一看你就懂,超详细java中的ClassLoader详解

本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 ClassLoader翻译过来就是类加载器,普通的java开发者其实用到的不多,但对于某些框架开发者来说却非常常见。理解ClassLoader的加载机制,也有利于我们编写出更高效的代码。ClassLoader的具体作用就是将class文件加载到jvm虚拟机中去,程序就可以正确运行了。但是,jvm启动的时候,并不会一次性加载所有的...

frank 的专栏 34万+

springboot自定义ClassLoader实现同一个jar支持多版本的使用场景【附源码】

springboot自定义ClassLoader实现同一个jar支持多版本加载使用的方案,demo 源码验证在同一个系统既要支持hive3.1.0版本同时又要支持hive2.1.1版本的数据源功能;

新方之玉的IT专栏 4390

UE5游戏逆向实战:用FModel提取.pak文件中的3D模型(附Dumper-7避坑指南)

本文详细介绍了如何使用FModel工具从UE5游戏的.pak文件中提取3D模型,并提供了Dumper-7的避坑指南。内容涵盖FModel工具链配置、UE5特有的unversioned properties问题解决方案、Dumper-7实战流程以及模型后处理技巧,帮助开发者高效获取游戏资产。

weixin_30872499的博客 422

Android:图解classloader加载class的流程及自定义ClassLoader

java应用环境中不同的class分别由不同的ClassLoader负责加载。 一个jvm中默认的classloader有Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader,分别各司其职: Bootstrap ClassLoader    负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的rt

Alostz 3264

基于 YOLO + SAM 的自动图像标注实战

摘要: 本文提出一种基于YOLO检测和SAM分割的自动化数据标注流水线方案,通过YOLO定位目标并生成检测框,再以检测框为提示驱动SAM完成精细分割,最终输出YOLO格式的标注文件。该方案将人工标注升级为半自动流程,显著提升标注效率,尤其适用于多类别、大规模图像的实例级标注需求。代码模块化设计支持模型灵活替换,并集成异常处理与进度可视化功能。虽依赖YOLO检测质量且对小目标存在局限,但作为工程落地方案,可有效降低私有数据集构建成本,适用于工业检测、遥感等场景的冷启动标注。

qq_64366203的博客 1147

Supervisor 安装与使用

一、Supervisor 介绍 Supervisor 是一个用 Python 编写的进程管理工具,它可以用于监控和控制类 UNIX 操作系统上的多个进程。它是一个客户端/服务器系统,其中 Supervisor 的服务器端称为 supervisord,负责启动管理的子进程、响应客户端命令、重启崩溃或退出的子进程、记录子进程的 stdout 和 stderr 输出,以及处理子进程生命周期中的事件。客...

疯子丶pony的博客 3863

[转]图解classloader加载class的流程及自定义ClassLoader

java应用环境中不同的class分别由不同的ClassLoader负责加载。一个jvm中默认的classloader有Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader,分别各司其职: Bootstrap ClassLoader 负责加载java基础类,主要是 %JRE_HOME/lib/ 目录...

achong0088的博客 81

Qwen2.5-7B大模型实战:从零部署到高效推理全流程解析

本文详细解析了Qwen2.5-7B大模型从零部署到高效推理的全流程。内容涵盖环境准备、模型下载、使用Transformers进行核心对话推理,并深入介绍了vLLM与TGI生产级服务部署、GPTQ/AWQ量化技术以降低显存消耗,以及llama.cpp、Ollama等本地推理方案。旨在帮助开发者快速掌握部署技巧,实现大模型在消费级硬件上的高效运行。

weixin_29061425的博客 490

图解classloader加载class的流程及自定义ClassLoade

转载请注明作者longdick http://longdick.iteye.com java应用环境中不同的class分别由不同的ClassLoader负责加载。 一个jvm中默认的classloader有Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader,分别各司其职: Bootstrap ClassLoader

jiangxindu1的专栏 698

S32的进阶之路->3,S32DS新建/删除/导入工程

右击工程名,点击Delect进行工程删除。选中Delect project contents on disk则会彻底删除工程,不选中Delect project contents on disk工程文件会保存在工作空间中。在Improt Projects中选择工程所在文件夹,选中所需要导入的工程,勾选Copy projects into workspace。选中目标示例工程,点击Finish,完成创建工程。导入已有工程,右击右击Project Explorer空白处,选择Import。

LC_8575的博客 2226

实战指南:如何用Frida绕过某梆加固的Anti-Frida检测(附完整脚本)

本文深入剖析了企业级加固方案中的Anti-Frida检测机制,并提供了实战对抗策略。通过分析基于文件系统、内存特征、行为及环境的多层次检测原理,文章详细介绍了如何定位检测逻辑、绕过maps文件扫描、对抗内存与行为特征检测,并附上了针对某梆加固的完整绕过脚本与系统化工程方案。

weixin_42527589的博客 600
上一篇: 源码解读Mybatis List列表In查询实现的注意事项
下一篇: 运行jar应用程序引用其他jar包的四种方法
ppby2002
博客等级 码龄23年 65粉丝 104原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值