總的來講,當動態加載一個資源時,至少有三種類加載器可供選擇:web
那麼這三種類加載器的使用場景分別是什麼呢?編程
1、系統類加載器(也被稱爲應用類加載器)(system classloader)服務器
這個類加載器處理classpath環境變量所指定的路徑下的類和資源,能夠經過ClassLoader.getSystemClassLoader()方法以編程式訪問。全部的ClassLoader.getSystemXXX()API方法也是經過這個類加載器訪問。你們應該不多寫代碼來顯式調用,而是以其它的類加載器委託給系統類加載器來代替。不然,當系統類加載器是JVM建立的最後一個類加載器時你的代碼將只能工做在簡單的命令行應用中。只要你把代碼遷移到EJB,web應用,或Java Web Start應用中確定會出問題.spa
2、當前類加載器(current classloader).net
當前類加載器加載和定義當前方法所屬的那個類。這個類加載器在你使用帶單個參數的Class.forName()方法,Class.getResource()方法和類似方法時會在運行時類的連接過程當中被隱式調用。它也出如今像X.class語法的字母調用中。命令行
3、當前線程的上下文類加載器( the current thread context classloader)線程
線程上下文類加載器是在J2SE中被引進的。每個線程分配一個上下文類加載器(除非線程由本地代碼建立)。該加載器是經過Thread.setContextClassLoader()方法來設置。對象
若是你在線程構造後不調用這個方法,這個線程將會從它的父線程(這裏的父線程是指執行建立新線程對象語句的線程)中繼承上下文類加載器。若是你在整個應用中不作任何設置,全部線程將以系統類加載器做爲它們本身的上下文加載器。重要的是明白自從Web和J2EE應用服務器爲了像JNDI,線程池,組件熱部署等特性而採用複雜的類加載器層次結構後,這(譯者注:指整個應用中不作任何設置)是不多見的狀況。blog
上下文類加載器提供了一個後門繞過在J2SE中介紹的類的加載委託機制。一般狀況下,一個JVM中的全部類加載器被組織成一個層次結構,使得每個類加載器(除了啓動整個JVM的原始類加載器)都有一個父加載器。當被要求加載一個類時,每個類加載器都將先委託父加載器來加載,只有父加載器都不能成功加載時當前類加載器纔會加載。繼承
有時這種加載順序不能正常工做,一般發生在有些JVM核心代碼必須動態加載由應用程序開發人員提供的資源時。以JNDI舉例:它的核心內容(從J2SE1.3開始)在rt.jar中的引導類中實現了,可是這些JNDI核心類可能加載由獨立廠商實現和部署在應用程序的classpath中的JNDI提供者。這個場景要求一個父類加載器(這個例子中的原始類加載器,即加載rt.jar的加載器)去加載一個在它的子類加載器(系統類加載器)中可見的類。此時一般的J2SE委託機制不能工做,解決辦法是讓JNDI核心類使用線程上下文加載器,從而有效創建一條與類加載器層次結構相反方向的「通道」達到正確的委託。
參考:http://blog.csdn.net/peter_k/article/details/1667685