`

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

阅读更多

/**
*  转载请注明作者longdick    http://longdick.iteye.com
*
*/

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。

代码示例:
 

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




由于classloader 加载类用的是全盘负责委托机制。所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入。
所以,当我们自定义的classloader加载成功了com.company.MyClass以后,MyClass里所有依赖的class都由这个classLoader来加载完成。

自定义ClassLoader在某些应用场景还是比较适用,特别是需要灵活地动态加载class的时候。
下面这篇文章列出了其中一种自定义ClassLoader的应用场景,有兴趣的同学可以参考下:
http://longdick.iteye.com/blog/332580

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

 

  • 大小: 155 KB
分享到:
评论

相关推荐

    Java实现热加载完整代码;Java动态加载class;Java覆盖已加载的class;Java自定义classloader

    让Java支持热加载是个不错的想法。如何做到的呢? 1. 定义好接口和实现类 2. 让代理类通过反射的方式调用实现类,对外暴露的是代理类。...Java动态加载class; Java覆盖已加载的class; Java自定义classloader;

    自定义Java类加载器demo

    自定义Java类加载器demo,自定义了一个classLoader,重写了loadClass 和findClass,注意 loadClass打破了双亲委派机制,所有的类都要在自定义的class文件中找到,而findClass遵循了双亲委派机制

    掌握Java类加载器

    类加载器是Java最强大的特征之一。但是开发者常常忘记类加载组件。类加载器是在运行时负责寻找和加载类...默认状态下,应用程序的每个类由java.lang.ClassLoader加载。因为它可以被继承,所以可以自由地加强其功能。

    MyCLRepl:自定义 Scala REPL 示例以添加自定义 ClassLoader 和自定义 REPL 命令

    自定义 ClassLoader 加载任何类时的类名。 ":myCommand" 命令位于默认 REPL 命令之上。 scala > val hello = " hello " MyClassLoader loads classOf < root>.$line3 <<中略>> MyClassLoader loads classOf ...

    indexed-classloader:一个自定义的 JVM 类加载器,它索引类路径元素以获得更快的类资源位置

    索引类加载器一个自定义的 JVM 类加载器,它为类路径元素编制索引,以便更快地定位类/资源。 构建: ./make-jar.sh 要使用,将indexed-classpath.jar添加到类路径并设置-Djava.system.class.loader=org.pantsbuild....

    MD5Util.class

    class文件,用于自定义ClassLoader加载文件使用; 类加载器是负责加载类的对象。ClassLoader 类是一个抽象类。如果给定类的二进制名称,那么类加载器会试图查找或生成构成类定义的数据。一般策略是将名称转换为某个...

    Android中动态载入自定义类

    这种自定义类加载机制可以使用于一些场景: dex文件只能包含最多64K的函数引用,对于大型的程序如果超过了该数字,就可以通过把程序打包为多个dex文件来实现,在程序运行的时候在加载这些需要的类 一些开发框架可以通过...

    java 类加载器 双亲委派 根加载器、扩展类加载器、系统类加载器

    类加载器分为根加载器(bootstrap classloader)、扩展类加载器(ext classloader)、系统类加载器(system classloader)、自定义类加载器(通常继承java.net.URLClassLoader,重写findClass()),它们的关系通常...

    Java虚拟机JVM类加载初始化

    1):本地编译好的class中直接加载 2):网络加载:java.net.URLClassLoader可以加载url指定的类 3):从jar、zip等等压缩文件加载类,自动解析jar文件找到class文件...而由用户自定义的类加载器所加载的类会被卸载掉!

    Java发展史_&_Java9、10新特性

    主要原因是JVM需要加载rt.jar,不管其中的类是否被classloader加载,第一步整个jar都会被JVM加载到内存当中去,模块化可以根据模块的需要加载程序运行需要的class。 在引入了模块系统之后,JDK 被重新组织成 94 ...

    LoadedApkPluginProject.zip

    基于Android9.0的源码分析,自定义LoadedApk和ClassLoader来加载插件的Class文件

    Java类加密2.0版本,无限制

    运行时,加密后的CLASS文件要能正常加载,需要使用我们提供的动态库lanswon.dll。执行java时带上参数 -agentlib:<动态库文件所在路径>\lanswon 注意:不要加文件后缀.dll,直接使用文件的名字部分(classloader)! ...

    java-homework

    (必做)自定义一个Classloader,加载一个Hello.xlass文件,执行hello方法,此文件内容是一个Hello.class文件所有字节(x = 255-x)处理后的文件。 3。 (必做)画一张图,展示Xmx,Xms,Xmn,Meta,DirectMemory...

    Java类加密程序

    <br>运行方式 运行时,加密后的CLASS文件要能正常加载,需要使用我们提供的动态库hidea.dll。执行java时带上参数 -agentlib:<动态库文件所在路径>\hidea 注意:不要加文件后缀.dll,直接使用文件的...

    Java版水果管理系统源码-java-advanced:java-高级

    基于自定义Classloader实现类的动态加载和卸载:需要设计加载和卸载。 基于自定义Classloader实现模块化机制:需要设计模块化机制。 使用xar作为模块,实现xar动态加载和卸载:综合应用前面的内容。 NIO 常规 使用 ...

    DelegatingGroovyClassloader

    简单委托 Groovy 类加载器描述这是一个使用自定义类加载器的简单项目。 简单的想法是嵌入 GroovyClassLoader,并且所以,能够使用 Groovy 语言的所有能力,但是这还不够。 目标是能够暴露一个普通的 ClassLoader ...

    day021-反射和注解笔记和代码.rar

    loader:可以指定一个类加载器加载字节码文件 2. 全限定类名.class 3. 对象名.getClass() Class类中方法newInstance():创建当前字节码对象(只能调用无参且是public修饰的构造...

    Android插件框架Android-Plugin-Framework.zip

    DexClassLoader的parent设置为宿主程序的classloader,即可将主程序和插件程序的class贯通 2、插件apk的资源 通过构造插件apk的AssetManager和Resouce类即可。 本项目最关键一点功能、也是和网上其他插件项目...

    汪文君高并发编程实战视频资源全集

    │ 高并发编程第二阶段45讲、ClassLoader加载阶段发生的故事.mp4 │ 高并发编程第二阶段46讲、ClassLoader链接阶段(验证,准备,解析)过程详细介绍.mp4 │ 高并发编程第二阶段47讲、ClassLoader初始化阶段详细...

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第二阶段45讲、ClassLoader加载阶段发生的故事.mp4 │ 高并发编程第二阶段46讲、ClassLoader链接阶段(验证,准备,解析)过程详细介绍.mp4 │ 高并发编程第二阶段47讲、ClassLoader初始化阶段详细...

Global site tag (gtag.js) - Google Analytics