在Java 应用开发过程中,可能会需要创建应用自己的类加载器。典型的场景包括实
现特定的Java 字节代码查找方式、对字节代码进行加密/解密以及实现同名 Java 类
的隔离等。创建自己的类加载器并不是一件复杂的事情, 只需要继承自
java.lang.ClassLoader 类并覆写对应的方法即可。java.lang.ClassLoader 中提供的方法
有不少,下面介绍几个创建类加载器时需要考虑的:
defineClass():这个方法用来完成从Java字节代码的字节数组到java.lang.Class的转
换。这个方法是不能被覆写的,一般是用原生代码来实现的。
findLoadedClass():这个方法用来根据名称查找已经加载过的Java类。一个类加
载器不会重复加载同一名称的类。
findClass():这个方法用来根据名称查找并加载Java类。
loadClass():这个方法用来根据名称加载Java类。
resolveClass():这个方法用来链接一个Java类。
这里比较 容易混淆的是findClass()方法和loadClass()方法的作用。前面提到过,在
Java 类的链接过程中,会需要对Java 类进行解析,而解析可能会导致当前Java 类所
引用的其它Java 类被加载。在这个时候,JVM 就是通过调用当前类的定义类加载器
的loadClass()方法来加载其它类的。findClass()方法则是应用创建的类加载器的扩展
点。应用自己的类加载器应该覆写findClass()方法来添加自定义的类加载逻辑。
loadClass()方法的默认实现会负责调用findClass()方法。
前面提到,类加载器的代理模式默认使用的是父类优先的策略。这个策略的实现是
封装在loadClass()方法中的。如果希望修改此策略,就需要覆写loadClass()方法。
下面的代码给出了自定义的类加载的常见实现模式:
public class MyClassLoader extends ClassLoader {
protected Class<?> findClass(String name) throws
ClassNotFoundException {
byte[] b = null; //查找或生成Java类的字节代码
return defineClass(name, b, 0, b.length);
}
}
|
|