轉
自定義classloader相信很多人都用過,網上文章也有很多。但如何使用自定義的classloader有時確實比較頭痛。
如果啟動入口自己可以控制還好說,大不了通過自定義classloader載入所有類就可以了,但如果控制不了,比如說是通過tomcat或指令碼來啟動的,但又要用自定義的classloader來載入外部類,那就鬱悶了。
我碰到的情形就是如此,其中的classloaderc是tomcat的類載入器,而classloaderd是自定義的類載入器。通常來說,我們只能選擇訪問c或d其中乙個下面的類。有沒辦法能同時訪問它們下兩個的類呢?
其中一種辦法是thread.currentthread().setcontextclassloader。相對比較方便,但這在多執行緒環境下很容易產生問題。
還有一種辦法是通過反射呼叫,修改classloaderc的parent為classloaderd。我們知道classloader的委託機制是先讓parent(父)類載入器尋找,只有在parent找不到的時候才從自己的類路徑中去尋找。這樣我們通過修改parent就能達到同時訪問的目的。當然,由於parent是私有的,而且沒有提供寫方法,所以還需要用反射來設定。
之前還嘗試了另一種方法,即classloader.addclass,但發現類是進去了,但package裡沒有,還是會載入不到類。
public class containerclassloader extends classloader
/**
* 初始化
*/
public static void init() catch (exception e)
} @suppresswarnings()
@override
public class loadclass(string name, boolean resolve) throws classnotfoundexception
return super.loadclass(name, resolve);
} /**
* 將this替換為指定classloader的parent classloader
* * @param classloader
*/
private void addthistoparentclassloader(classloader classloader) throws exception
}
另外,在過程中還碰到spring載入時,classloader還沒修改的問題。後來通過在web.xml中增加listener-class來實現。
private void addthistoparentclassloader(classloader classloader) throws exception catch (exception e)
//將當前classloader的parent classloader修改為本物件
field = classloader.class.getdeclaredfield("parent");
field.setaccessible(true);
field.set(classloader, this);
}
自定義類載入器
注 class.forname name,initialize,loader 帶參函式也可控制是否載入static塊。並且只有呼叫了newinstance 方法採用呼叫建構函式,建立類的物件 如果乙個類載入器收到了類載入的請求,它首先不會自己去嘗試載入這個類,而是把請求委託給父載入器去完成,依次向上...
自定義類載入器
我們自己約定的需求如下,我們從外部路徑 tmp myclasspath 載入類 具體實現如下 public class myclassloader extends classloader catch ioexception e 測試 public static void main string ar...
JAVA類載入機制以及如何自定義類載入器
雙親委派機制描述 本文主要以tomcat7為例說明類載入機制,大家也可以參考tomcat7的類載入機制的官方文件。tomcat7總的classloader結構如下圖 各個類載入器載入類的範圍 載入順序預設如下 如果設定了,載入順序如下 jdk的解釋是這樣的 並不是給執行緒設定了contextclas...