实现自定义 classLoader
每个自定义加载器必须直接或间接扩展 java.lang.ClassLoader 类。主要的扩展点是以下方法:
findClass(String)- 如果类加载器遵循类加载的标准委托模型,则重载此方法。loadClass(String, boolean)- 重载此方法以实现替代委派模型。findResource和findResources- 重载这些方法以自定义资源加载。
负责从字节数组中实际加载类的 defineClass 方法是 final 以防止重载。在调用 defineClass 之前,需要执行任何自定义行为。
这是一个从字节数组加载特定类的简单:
public class ByteArrayClassLoader extends ClassLoader {
private String classname;
private byte[] classfile;
public ByteArrayClassLoader(String classname, byte[] classfile) {
this.classname = classname;
this.classfile = classfile.clone();
}
@Override
protected Class findClass(String classname) throws ClassNotFoundException {
if (classname.equals(this.classname)) {
return defineClass(classname, classfile, 0, classfile.length);
} else {
throw new ClassNotFoundException(classname);
}
}
}
由于我们只重写了 findClass 方法,所以当调用 loadClass 时,这个自定义类加载器将表现如下。
- 类加载器的
loadClass方法调用findLoadedClass来查看此类加载器是否已加载具有此名称的类。如果成功,则生成的Class对象将返回给请求者。 - 然后
loadClass方法通过调用loadClass调用委托给父类加载器。如果父进程可以处理请求,它将返回一个Class对象,然后将该对象返回给请求者。 - 如果父类加载器无法加载类,则
findClass会调用我们的覆盖findClass方法,传递要加载的类的名称。 - 如果请求的名称与
this.classname匹配,我们调用defineClass从this.classfile字节数组加载实际的类。然后返回生成的Class对象。 - 如果名称不匹配,我们扔
ClassNotFoundException。