自定义类加载器
流程
- 继承ClassLoader类;
- 检查请求的类型是否已经被这个类加载器装载到命名空间了,如果已经装载直接返回;
- 委派类加载请求给父类加载器,如果父类加载器能够完成,则返回父类加载器加载的Class实例;
- 调用本类加载器的findClass()方法,获取对象字节码,获取到调用defineClass()导入类型到方法区;获取不到或其他原因导致失败,返回异常给loadClass(),再转抛异常,终止加载。
说明:两个类加载器加载相同的类,JVM认为是不同的类。
代码实现
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;/**
自定义类加载器
/
public class FileSystemClassLoader extends ClassLoader{
private String root; // 类路径public FileSystemClassLoader(String root){
this.root = root;
}
/**
Finds the class with the specified binary name.
This method should be overridden by class loader implementations that
follow the delegation model for loading classes, and will be invoked by
the {@link #loadClass <tt>loadClass</tt>} method after checking the
parent class loader for the requested class. The default implementation
throws a <tt>ClassNotFoundException</tt>.
@param name The binary name of the class
@return The resulting <tt>Class</tt> object
@throws ClassNotFoundException If the class could not be found
@since 1.2
/
@Override
protected Class findClass(String name) throws ClassNotFoundException { Class c = findLoadedClass(name); // 查找对应name的Classif (c != null){ // 找到直接返回
return c;
} else{
ClassLoader parent = this.getParent(); try { c = parent.loadClass(name); // 委派给父类 } catch (ClassNotFoundException e) { e.printStackTrace(); } if (c != null){ return c; } else{ byte[] classData = getClassData(name); // 返回字节数据 if (classData != null){ c = defineClass(name,classData,0,classData.length); } else{ throw new ClassNotFoundException(); } }
}
// return super.findClass(name);
return c;}
private byte[] getClassData(String classname){
String path = root+"/"+classname.replace('.','/')+".class";// 将流中的数据转成字节数组
try(InputStream is = new FileInputStream(path); ByteArrayOutputStream baos = new ByteArrayOutputStream();) {byte[] buffer = new byte[1024]; int temp = 0; while((temp=is.read(buffer))!=-1){ // 读取数据并写入 baos.write(buffer,0,temp); } return baos.toByteArray();
} catch (Exception e){
e.printStackTrace(); return null;
}
}
}