動態程式設計之classloader

wafodis發表於2004-09-17
這個周看了很多有關classloader的文章,再加上自己的一點實踐拿出來跟大家分享,如有謬誤,懇請指正。首先簡單介紹一下classloader的結構:每個構造好的類在某種意義上是由裝入它的類裝入器所“擁有”,類裝入器通常保留它們所裝入類的對映,從而當再次請求某個類時,能透過名稱找到該類,而裝載機則有可能將類儲存在快取或記憶體之中,每個類裝入器還保留對父類裝入器的引用,整個classloader結構是一個類裝入器樹,下層的裝入器由上層的裝入器裝入,而這些裝入器都使用java語言編成,既然這樣那根裝入器是被什麼裝進去的呢?我猜既然java語言都需要classloader裝進去的話那根classloader一定不是java編寫的了,可能是彙編或者c完成的(這裡沒查資料,不是很準確)。那麼關於動態載入新的類這一主題我曾經想得很簡單,覺得無非就是另起一個執行緒監視給定的目錄然後掃入目錄下的類把這些類載入進虛擬機器裡就行了,試驗了很多次這樣的想法都沒成功,最後查資料才知道原因是各個執行緒的classloader都不一樣而且不會去主動溝通,每個執行緒只能用到當前的classloader以及系統classloader也就是,裝載環境變數classpath下設定的那些類的classloader,所以另起一個執行緒所載入進來的類主執行緒根本用不成。至於要怎麼實現,可以參考IBM技術文件,也可以參考開源專案JBOSS伺服器的原始碼,我的看法是,他們的做法可以說是殊途同歸,IBM文件上採用了繼承URLClassLoader的方法,透過getSystemClassLoader()方法取得當前classloader,並把它作為父類作為引數建立自己的classloader;而JBOSS的做法更為巧妙,它將當前執行緒的classloader取得後暫時存起來,並且用給定URL建立的classloader取代當前classloader,當用完所需要路徑下的類之後再恢復當前執行緒,這樣就達到了把檢測和呼叫新類的任務分離出去給子執行緒做的一個目的,構思很是巧妙,具體實現可以參考JBOSS的原始碼,下載地址是http://prdownloads.sourceforge.net/jboss/jboss-3.0.1RC1-src.tgz?download。至於動態呼叫給與的新類中的各種函式的方法,要用到java的Reflection機制,相信各位都不陌生,可以查閱sun的載線文件

相關文章