淺析Context Class Loader
1 前言
對于一般的Java應(yīng)用而言,類裝載器是透明的,我們在做普通的Java桌面應(yīng)用程序和Web程序的時候也很少會與ClassLoader打交道。但是當(dāng)我們深入地研究一些WebServer(如Tomcat)的時候,發(fā)現(xiàn)里面用到了很復(fù)雜的自定義類裝載器體系結(jié)構(gòu),想要了解其工作過程首先就要理解它是如何載如類的。此外,當(dāng)我們明明在ClassPath下指定了正確的jar包,卻莫名其妙地受到ClassNotFound錯誤,或者我們放到ClassPath下的類沒有被正確載入的時候,就需要和ClassLoader打交道了。這里我不打算討論基本的JVM的類裝載器體系結(jié)構(gòu)和原理,因為這些東西已經(jīng)在《Java深度歷險》或者《Inside Of JVM》里講的很透徹了。本文旨在分享一下我對于各種文檔上都很少提及的Context Class Loader的一些理解。雖然不是點到為止,但是肯定多有疏漏之處,希望對此有研究的朋友留言幫我補充,現(xiàn)行謝過。
2準備
通常情況下,類裝載器共有4種,即啟動類裝載器、EXT類裝載器、App類裝載器和自定義類裝載器。他們之間的階層情況如下圖左面所示,他們都有著不同的載入規(guī)則,并且通過向上代理的方式來進行。而本文所提到的Context Class Loader并不是一種新的裝載器類型,而是一種抽象的說法,它的具體表現(xiàn)形式為:調(diào)用Thread.getCurrentThread().getContextClassLoader()所返回的那個ClassLoader。它和JVM缺省的類裝載器以及自定義類裝載之間是什么關(guān)系呢?下面通過一個實驗來看一下。
3 實戰(zhàn)演練
(1)步驟一
上圖進行了這樣一個實驗:首先一個名為Class(1)的類中啟動MainThread(其實就是這個類里面有main函數(shù)的意思啦),注意這個類的名字后面標出了其所在的路徑(即ClassPath),然后在里面進行測試,發(fā)現(xiàn)目前它的裝載器和當(dāng)前線程(MainThread)的ContextClassLoader都是AppClassLoader。然后Class(1)啟動了一個新線程Class(2)。這里的Class(2)是一個Thread的子類,執(zhí)行Class(2)代碼的線程我稱之為Thread-0。
(2)步驟二
上圖可以看到Class(2)的裝載器和ContextClassLoader同樣都是AppClassLoader。隨后我在Class(2)中創(chuàng)建了一個新的URLCLassLoader,并用這個ClassLoader來載入另一個和Class(1)不在同一個ClassPath下的類Class(3)。此時我們就可以看到變化:即載入Class(3)的裝載器是URLClassLoader,而ContextClassLoader還仍然是AppClassLoader。
(2)步驟三
最后我們在Class(3)中啟動了一個線程類Class(4),發(fā)現(xiàn)Class(4)也是由URLClassLoader載入的,而此時ContextClassLoader仍然是AppClassLoader。
在整個過程中,裝載類的ClassLoader發(fā)生了變化,由于線程類Class(4)是由Class(3)啟動的,所以裝載它的類裝載器就變成了URLClassLoader。與此同時,所有線程的ContextClassLoader都繼承了生成該線程的ContextClassLoader--AppClassLoader。
如果我們在第二步的結(jié)尾執(zhí)行了綠色框中的代碼:setContextClassLoader(),則結(jié)果就會變成下面這個樣子:
我們可以清楚地看到,由于Thread-0將其ContextClassLoader設(shè)置成了URLClassLoader,而Thread-1是在Thread-0里面生成的,所以就繼承了其ContextClassLoader,變成了URLClassLoader。
3 后記
這里列出的試驗可能不見得全面,但相信足以說明問題,應(yīng)該可以說明ContextClassLoader與其它類裝載器的區(qū)別所在。但有可能ContextClassLoader還有其他的不同之處,希望有這方面經(jīng)驗的朋友一起討論。
發(fā)表于 @ 2008年09月24日 22:59:00 | 評論( 2 ) | 編輯| 舉報| 收藏
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點擊舉報。