實現自定義 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。