/**
* 转载请注明作者longdick http://longdick.javaeye.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实现,比如
- DE style="FONT-FAMILY: 'Courier New', Courier, monospace; WHITE-SPACE: pre; FONT-SIZE: 1em">java.net.URLClassLoader DE>
- DE style="FONT-FAMILY: 'Courier New', Courier, monospace; WHITE-SPACE: pre; FONT-SIZE: 1em">java.security.SecureClassLoader DE>
- DE style="FONT-FAMILY: 'Courier New', Courier, monospace; WHITE-SPACE: pre; FONT-SIZE: 1em">java.rmi.server.RMIClassLoader DE>
- DE style="FONT-FAMILY: 'Courier New', Courier, monospace; WHITE-SPACE: pre; FONT-SIZE: 1em">sun.applet.AppletClassLoader DE>
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的时候。
相关推荐
1. **自定义ClassLoader**:Java允许我们创建自定义的ClassLoader,这通常用于实现动态加载类的需求。自定义ClassLoader需要重写`findClass()`或`loadClass()`方法。`loadClass()`方法是类加载的入口,它会调用`find...
让Java支持热加载是个不错的想法。如何做到的呢? 1. 定义好接口和实现类 2. 让代理类通过反射的方式调用实现类,对外暴露的是代理类。 3. 自定义URLClassLoader。检查实现类.class文件的...Java自定义classloader;
双亲委派模型使得系统类(如java.*开头的类)由Bootstrap ClassLoader加载,而用户自定义类由应用程序类加载器(AppClassLoader)加载。这避免了类的冲突,保持了系统类库的稳定性。但有时我们可能需要打破这种模型...
【图解版】深入分析ClassLoader类加载工作机制,从原理到JVM的装载过程,详情分析了ClassLoader加载类以及自定义类加载器的过程,不可用于商业用途,如有版权问题,请联系删除!
自定义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)`方法。这个方法是加载类的核心,它首先检查该类是否已经被加载,然后决定是从父类加载器还是从自己的实现中加载类的字节...
默认情况下,Java使用系统ClassLoader(Bootstrap ClassLoader)加载JDK核心库,然后是Extension ClassLoader加载扩展库,最后是App ClassLoader加载应用类路径(ClassPath)下的类。当这些默认ClassLoader无法满足...
在实际应用中,我们可以通过反射API来使用自定义ClassLoader加载的类。例如,我们可以创建一个`Class`对象,然后调用`newInstance()`方法来创建该类的实例。 总结来说,Java ClassLoader的定制是一项强大的技术,它...
3. System ClassLoader(也称为AppClassLoader):加载`CLASSPATH`环境变量指定的类,以及应用主类路径(class path)上的类。 4. WebLogic特定的ClassLoaders: - Ear ClassLoader:加载EAR应用的全局库(如lib...
- 自定义ClassLoader通常需要重写`loadClass()`方法,该方法在找不到类时调用`findClass()`进行实际的加载操作。 - 在`ClassLoaderDemo`这个例子中,可能就展示了如何创建一个自定义的ClassLoader,从非标准位置...
3. 如果类还未加载,ClassLoader会在指定的路径(例如类路径,classpath)下寻找对应的.class文件。 4. 找到类文件后,ClassLoader读取文件内容并将其转换为字节码。 5. 接下来,字节码会被验证确保符合Java语言规范...
// 自定义ClassLoader加载 this.getClass().getClassLoader().loadClass("com.anbai.sec.classloader.TestHelloWorld"); ``` 这两种方式在需要动态加载未知类或延迟初始化类的场景下非常有用,比如插件系统、热...
这些代码可能展示了如何创建自定义ClassLoader,以及如何使用ClassLoader加载非标准位置的类。通过分析这些示例,我们可以更好地理解ClassLoader的工作机制。 总的来说,理解和掌握JVM ClassLoader对于优化Java应用...
为了实现动态加载,我们需要创建自定义的ClassLoader,并重写其关键方法,如`findClass()`。 首先,我们要理解APK的加载过程。当Android系统启动一个应用时,会通过PathClassLoader加载APK中的`classes.dex`文件,...
总结起来,Android 动态加载Class涉及到的关键技术包括:自定义ClassLoader、Dex文件操作、反射、权限管理以及Android的类加载机制。这一技术在提高程序灵活性和维护性的同时,也需要开发者对Android系统的深入了解...