/**
* 转载请注明作者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
相关推荐
1. **自定义ClassLoader**:Java允许我们创建自定义的ClassLoader,这通常用于实现动态加载类的需求。自定义ClassLoader需要重写`findClass()`或`loadClass()`方法。`loadClass()`方法是类加载的入口,它会调用`find...
让Java支持热加载是个不错的想法。如何做到的呢? 1. 定义好接口和实现类 2. 让代理类通过反射的方式调用实现类,对外暴露的是代理类。...Java动态加载class; Java覆盖已加载的class; Java自定义classloader;
双亲委派模型使得系统类(如java.*开头的类)由Bootstrap ClassLoader加载,而用户自定义类由应用程序类加载器(AppClassLoader)加载。这避免了类的冲突,保持了系统类库的稳定性。但有时我们可能需要打破这种模型...
自定义Classloader允许开发者根据特定需求定制类的加载逻辑,例如加密类文件、隔离不同版本的库或者动态加载代码。本文将深入探讨自定义Classloader的使用。 一、Classloader的工作原理 Java的类加载机制遵循双亲...
自定义ClassLoader通常是为了满足特定的加载需求,例如从网络、数据库或非标准路径加载类。下面是一个简单的自定义ClassLoader的示例: ```java public class MyClassLoader extends ClassLoader { private String...
接下来我们通过一个简单的自定义类加载器示例来进一步了解类加载器的工作流程。 ```java package test.classloader; import java.io.*; import org.apache.log4j.Logger; public class MyClassLoader extends ...
通过自定义类加载器并重写`loadClass()`方法,可以打破双亲委派模型。但是通常不推荐这样做,因为这可能引入类版本冲突和安全性问题。 5. **自定义类加载器** 开发者可以创建自己的类加载器来实现特定的加载逻辑...
Bootstrap ClassLoader加载JRE的核心库,Extension ClassLoader加载Java扩展目录下的类,而AppClassLoader则加载应用的主类路径(ClassPath)上的类。 接下来,我们来讨论“加密解密应用程序”。在Java环境中,为了...
在Java编程语言中,`Classloader`(类加载器)是一个至关重要的组件,它负责将类的`.class`文件从磁盘加载到JVM(Java虚拟机)内存中,使得程序能够执行。这篇博文主要围绕`Classloader`的`loadClass`方法进行深入...
- 自定义类加载器需要继承Java的`java.lang.ClassLoader`类,并重写`loadClass(String name)`方法。这个方法是加载类的核心,它首先检查该类是否已经被加载,然后决定是从父类加载器还是从自己的实现中加载类的字节...
自定义ClassLoader通常继承自java.lang.ClassLoader基类,并重写其关键方法,如`findClass(String name)`或`loadClass(String name)`。这两个方法用于根据类的全名查找并加载对应的字节码。在处理外部jar包时,我们...
接着,Extension ClassLoader加载扩展类库,然后是App ClassLoader加载应用程序的类路径下的类。每个ClassLoader都有其父ClassLoader,它们形成了一个层次结构,子ClassLoader可以委托父ClassLoader去加载类,避免了...
- 自定义ClassLoader通常需要重写`loadClass()`方法,该方法在找不到类时调用`findClass()`进行实际的加载操作。 - 在`ClassLoaderDemo`这个例子中,可能就展示了如何创建一个自定义的ClassLoader,从非标准位置...
3. 整合自定义ClassLoader:了解如何将自定义的ClassLoader集成到Java应用程序中,替换或扩展默认的加载行为。 4. 考虑Java 2版本的兼容性:学习如何修改你的ClassLoader以适应Java 2及以上版本的特性,比如支持...
这里我们将详细讨论ClassLoader的运行机制,特别是自定义ClassLoader的设计与实现。 ClassLoader的基本职责是根据类名动态加载对应的类文件。在Java中,类加载过程遵循双亲委派模型(Parent Delegation Model)。这...
// 自定义ClassLoader加载 this.getClass().getClassLoader().loadClass("com.anbai.sec.classloader.TestHelloWorld"); ``` 这两种方式在需要动态加载未知类或延迟初始化类的场景下非常有用,比如插件系统、热...
这些代码可能展示了如何创建自定义ClassLoader,以及如何使用ClassLoader加载非标准位置的类。通过分析这些示例,我们可以更好地理解ClassLoader的工作机制。 总的来说,理解和掌握JVM ClassLoader对于优化Java应用...
但是,如果我们的目标是动态加载额外的.dex文件,那么就需要自定义ClassLoader,比如继承DexClassLoader: ```java public class CustomClassLoader extends DexClassLoader { public CustomClassLoader(String ...
动态加载Class的核心在于自定义ClassLoader。在Android中,我们通常会继承 DexClassLoader 或 PathClassLoader 来实现这一功能。DexClassLoader 是Android系统提供的用于加载 dex 文件的类加载器,它继承自 ...
自定义ClassLoader则允许我们插入这个流程,按照自己的规则去查找和加载类。 在自定义ClassLoader时,主要需要覆写两个关键方法:`findClass()` 和 `loadClass()`。`loadClass()` 方法通常用于委托父类加载器加载类...