介绍
注意类加载器的体系并不是“继承”体系,而是一个“委派”体系。大多数类加载器首先会到自己的 parent 中查找类或者资源,如果找不到,才会在自己的本地进行查找。事实上,类加载器被定义加载那些在 parent 中无法加载到的类。
先大体了解一下 classloader 的 API
package java.lang;
public abstract class ClassLoader {
public Class loadClass(String name);
protected Class defineClass(byte[] b);
public ClassLoader getParent();
public URL getResource(String name);
public Enumeration getResources(String name);
}
ClassLoader分类
- BootStrap ClassLoader
称为启动类加载器,是 Java 类加载层次中最顶层的类加载器,负责加载 JDK 中的核心类库,如:rt.jar、resources.jar、charsets.jar等。
目录为$JAVA_HOME/jre/classes
或者使用如下配置 JVM 参数
-Xbootclasspath:<用:分隔的目录和zip/jar文件>
设置搜索路径以引导类和资源
-Xbootclasspath/a:<用:分隔的目录和zip/jar文件>
附加在引导类路径末尾
-Xbootclasspath/p:<用:分隔的目录和zip/jar文件>
置于引导类路径之前
- Extension ClassLoader
称为扩展类加载器,负责加载 Java 的扩展类库,默认加载 JAVA_HOME/jre/lib/ext 目录下的所有 jar。
目录为 $JAVA_HOME/jre/lib/ext
-
App ClassLoader
称为系统类加载器,负责加载应用程序 classpath 目录下的所有 jar 和 class 文件。
除了 Java 默认提供的三个 ClassLoader 之外,用户还可以根据需要定义自已的 ClassLoader,而这些自定义的 ClassLoader 都必须继承自 java.lang.ClassLoader 类,ExtensionClassLoader 和 AppClassLoader 也是继承自 java.lang.ClassLoader 类,但是 BootstrapClassLoader 没有继承ClassLoader,因为它不是一个普通的 Java 类,底层由 C++ 编写,已嵌入到了 JVM 内核当中,当 JVM 启动后,BootstrapClassLoader 也随着启动,负责加载完核心类库后,并构造 ExtensionClassLoader 和 AppClassLoader 类加载器。
自定义ClassLoader
因为 Java 中提供的默认 ClassLoader,只加载指定目录下的 jar 和 class ,如果我们想加载其它位置的类或 jar 时,默认的 ClassLoader 就不能满足我们的需求了,所以需要定义自己的 ClassLoader。
定义自已的类加载器分为两步:
- 继承 java.lang.ClassLoader
- 重写父类的 findClass 方法