07. 自定义类加载器
2020-02-19 本文已影响0人
ZFH__ZJ
第一个自定义类加载器
-
继承抽象类ClassLoader
public class MyTest16 extends ClassLoader{ }
-
定义classLoaderName,fileExtension两个成员变量
public class MyTest16 extends ClassLoader{ // 类加载器名字 private String classLoaderName; // 字节码文件扩展名 private final String fileExtension = ".class"; }
-
定义两个构造方法
public class MyTest16 extends ClassLoader{ // 类加载器名字 private String classLoaderName; // 字节码文件扩展名 private final String fileExtension = ".class"; public MyTest16(String classLoaderName) { // 使用getSystemClassLoader()返回的类加载器,即AppClassLoader作为该类加载器的父类加载器 super(); this.classLoaderName = classLoaderName; } public MyTest16(ClassLoader parent, String classLoaderName) { // 显式指定该类加载器的父类加载器 super(parent); this.classLoaderName = classLoaderName; } }
-
定义loadClassData()方法
public class MyTest16 extends ClassLoader{ // 类加载器名字 private String classLoaderName; // 字节码文件扩展名 private final String fileExtension = ".class"; public MyTest16(String classLoaderName) { // 使用getSystemClassLoader()返回的类加载器,即AppClassLoader作为该类加载器的父类加载器 super(); this.classLoaderName = classLoaderName; } public MyTest16(ClassLoader parent, String classLoaderName) { // 显式指定该类加载器的父类加载器 super(parent); this.classLoaderName = classLoaderName; } private byte[] loadClassData(String className) { InputStream is = null; byte[] data = null; ByteArrayOutputStream baos = null; try { is = new FileInputStream(new File(className + this.fileExtension)); baos = new ByteArrayOutputStream(); int ch = 0; while (-1 != (ch = is.read())){ baos.write(ch); } data = baos.toByteArray(); }catch (Exception e) { e.printStackTrace(); }finally { try { is.close(); baos.close(); }catch (Exception e) { e.printStackTrace(); } } return data; } @Override public String toString() { return "[" + this.classLoaderName + "]"; } }
-
重写findClass()方法
public class MyTest16 extends ClassLoader{ // 类加载器名字 private String classLoaderName; // 字节码文件扩展名 private final String fileExtension = ".class"; public MyTest16(String classLoaderName) { // 使用getSystemClassLoader()返回的类加载器,即AppClassLoader作为该类加载器的父类加载器 super(); this.classLoaderName = classLoaderName; } public MyTest16(ClassLoader parent, String classLoaderName) { // 显式指定该类加载器的父类加载器 super(parent); this.classLoaderName = classLoaderName; } @Override protected Class<?> findClass(String className) throws ClassNotFoundException { byte[] data = this.loadClassData(className); return this.defineClass(className, data, 0, data.length); } private byte[] loadClassData(String className) { InputStream is = null; byte[] data = null; ByteArrayOutputStream baos = null; try { is = new FileInputStream(new File(className + this.fileExtension)); baos = new ByteArrayOutputStream(); int ch = 0; while (-1 != (ch = is.read())){ baos.write(ch); } data = baos.toByteArray(); }catch (Exception e) { e.printStackTrace(); }finally { try { is.close(); baos.close(); }catch (Exception e) { e.printStackTrace(); } } return data; } @Override public String toString() { return "[" + this.classLoaderName + "]"; } }
定义第二个类加载器
在第一个类加载器基础上添加path字段,从什么地方加载 绝对路径
在findClass里面添加两个输出,这两个信息输出 说明findClass()方法被调用
public class MyTest16_2 extends ClassLoader{
// 类加载器名字
private String classLoaderName;
// 新增字段path 从什么地方加载 绝对路径
private String path;
// 新增set方法
public void setPath(String path) {
this.path = path;
}
// 字节码文件扩展名
private final String fileExtension = ".class";
public MyTest16_2(String classLoaderName) {
// 使用getSystemClassLoader()返回的类加载器,即AppClassLoader作为该类加载器的父类加载器
super();
this.classLoaderName = classLoaderName;
}
public MyTest16_2(ClassLoader parent, String classLoaderName) {
// 显式指定该类加载器的父类加载器
super(parent);
this.classLoaderName = classLoaderName;
}
@Override
protected Class<?> findClass(String className) throws ClassNotFoundException {
// 这两个信息输出 说明findClass()方法被调用
System.out.println("findClass invoked: " + className);
System.out.println("class loader name: " + this.classLoaderName);
byte[] data = this.loadClassData(className);
return this.defineClass(className, data, 0, data.length);
}
private byte[] loadClassData(String className) {
InputStream is = null;
byte[] data = null;
ByteArrayOutputStream baos = null;
// windows 系统 替换成\\
className = className.replace(".", "/");
try {
is = new FileInputStream(new File( this.path + className + this.fileExtension));
baos = new ByteArrayOutputStream();
int ch = 0;
while (-1 != (ch = is.read())){
baos.write(ch);
}
data = baos.toByteArray();
}catch (Exception e) {
e.printStackTrace();
}finally {
try {
is.close();
baos.close();
}catch (Exception e) {
e.printStackTrace();
}
}
return data;
}
@Override
public String toString() {
return "[" + this.classLoaderName + "]";
}
}