java应用环境中不一样的class分别由不一样的ClassLoader负责加载。
一个jvm中默认的classloader有Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader,分别各司其职: java
其中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的过程。
app
Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader三者的关系以下: jvm
Bootstrap ClassLoader是Extension ClassLoader的parent,Extension ClassLoader是App ClassLoader的parent。 url
可是这并非继承关系,只是语义上的定义,基本上,每个ClassLoader实现,都有一个Parent ClassLoader。 spa
能够经过ClassLoader的getParent方法获得当前ClassLoader的parent。Bootstrap ClassLoader比较特殊,由于它不是java class因此Extension ClassLoader的getParent方法返回的是NULL。 .net
了解了ClassLoader的原理和流程之后,咱们能够试试自定义ClassLoader。 server
关于自定义ClassLoader: blog
因为一些特殊的需求,咱们可能须要定制ClassLoader的加载行为,这时候就须要自定义ClassLoader了. 继承
自定义ClassLoader须要继承ClassLoader抽象类,重写findClass方法,这个方法定义了ClassLoader查找class的方式。
主要能够扩展的方法有:
findClass 定义查找Class的方式
defineClass 将类文件字节码加载为jvm中的class
findResource 定义查找资源的方式
若是嫌麻烦的话,咱们能够直接使用或继承已有的ClassLoader实现,好比
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加载一个Class的时候,这个Class所依赖的和引用的全部 Class也由这个classloader负责载入,除非是显式的使用另一个classloader载入。
因此,当咱们自定义的classloader加载成功了com.company.MyClass之后,MyClass里全部依赖的class都由这个classLoader来加载完成。
自定义ClassLoader在某些应用场景仍是比较适用,特别是须要灵活地动态加载class的时候。