/**java
* 转载请注明做者longdick http://longdick.iteye.com数组
*app
*/jvm
java应用环境中不一样的class分别由不一样的ClassLoader负责加载。
一个jvm中默认的classloader有Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader,分别各司其职:url
其中Bootstrap ClassLoader是JVM级别的,由C++撰写;Extension ClassLoader、App ClassLoader都是java类,都继承自URLClassLoader超类。
Bootstrap ClassLoader由JVM启动,而后初始化sun.misc.Launcher ,sun.misc.Launcher初始化Extension ClassLoader、App ClassLoader。spa
下图是ClassLoader的加载类流程图,以加载一个类的过程类示例说明整个ClassLoader的过程。.net
Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader三者的关系以下:code
Bootstrap ClassLoader是Extension ClassLoader的parent,Extension ClassLoader是App ClassLoader的parent。server
可是这并非继承关系,只是语义上的定义,基本上,每个ClassLoader实现,都有一个Parent ClassLoader。blog
能够经过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加载一个Class的时候,这个Class所依赖的和引用的全部 Class也由这个classloader负责载入,除非是显式的使用另一个classloader载入。
因此,当咱们自定义的classloader加载成功了com.company.MyClass之后,MyClass里全部依赖的class都由这个classLoader来加载完成。
自定义ClassLoader在某些应用场景仍是比较适用,特别是须要灵活地动态加载class的时候。
下面这篇文章列出了其中一种自定义ClassLoader的应用场景,有兴趣的同窗能够参考下: