自定義類載入器與spring的整合

2021-09-10 08:59:20 字數 1641 閱讀 2635

轉 

自定義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...