實現自定義 classLoader

每個自定義載入器必須直接或間接擴充套件 java.lang.ClassLoader 類。主要的擴充套件點是以下方法:

  • findClass(String) - 如果類載入器遵循類載入的標準委託模型,則過載此方法。
  • loadClass(String, boolean) - 過載此方法以實現替代委派模型。
  • findResourcefindResources - 過載這些方法以自定義資源載入。

負責從位元組陣列中實際載入類的 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 時,這個自定義類載入器將表現如下。

  1. 類載入器的 loadClass 方法呼叫 findLoadedClass 來檢視此類載入器是否已載入具有此名稱的類。如果成功,則生成的 Class 物件將返回給請求者。
  2. 然後 loadClass 方法通過呼叫 loadClass 呼叫委託給父類載入器。如果父程序可以處理請求,它將返回一個 Class 物件,然後將該物件返回給請求者。
  3. 如果父類載入器無法載入類,則 findClass 會呼叫我們的覆蓋 findClass 方法,傳遞要載入的類的名稱。
  4. 如果請求的名稱與 this.classname 匹配,我們呼叫 defineClassthis.classfile 位元組陣列載入實際的類。然後返回生成的 Class 物件。
  5. 如果名稱不匹配,我們扔 ClassNotFoundException