先來個例子:java
/** * 測試classloader加載路徑在哪裏<p> * main3 */ public static void main3(String[] args) { Properties props = new Properties(); //在src中的dyan/sendhttp包路徑下 // InputStream is = TestSendHttp.class.getClassLoader().getResourceAsStream("dyan/sendhttp/dyan.txt"); //在src下 InputStream is = TestSendHttp.class.getClassLoader().getResourceAsStream("dyan.txt"); //展現類加載器的父加載器,能夠確定是ExtClassLoader System.out.println(TestSendHttp.class.getClassLoader().getParent().toString()); try { props.load(is); String auther = props.get("auther").toString(); System.out.println(auther); } catch (IOException e) { e.printStackTrace(); } }
資源路徑:json
無論上面用哪一個輸入流,均可以讀取dyan.txt中的auther內容。api
結論:dom
從上面的結果能夠看出,AppClassLoader的搜索資源路徑是相對於src的編譯後路徑。測試
如個人機器src的編譯後路徑是TestProject/bin,則AppClassLoader的搜索資源路徑就包括spa
E:\core_wkspace\TestProject\bin。code
類加載器blog
JVM是經過一個稱爲ClassLoader東西來加載Class文件的,每當JVM啓動,ssl
它就會生成三個ClassLoader,它們分別是BootstrapLoader, ExtClassLoader 和AppClassLoader。資源
這三個ClassLoader做用是不一樣的,它們所加載的class文件也是不一樣的。
BootstrapLoader是用C++語言實現的,它所加載的是JVM中最底層的類,它加載時的搜索路徑是由sun.boot.class.path所指定的。
System.getProperty("sun.boot.class.path").split(";");
D:\tools\Java\jdk1.7.0_17\jre\lib\resources.jar
D:\tools\Java\jdk1.7.0_17\jre\lib\rt.jar
D:\tools\Java\jdk1.7.0_17\jre\lib\sunrsasign.jar
D:\tools\Java\jdk1.7.0_17\jre\lib\jsse.jar
D:\tools\Java\jdk1.7.0_17\jre\lib\jce.jar
D:\tools\Java\jdk1.7.0_17\jre\lib\charsets.jar
D:\tools\Java\jdk1.7.0_17\jre\lib\jfr.jar
D:\tools\Java\jdk1.7.0_17\jre\classes
ExtClassLoader是用來加載java的一些庫的,它加載時的搜索路徑是由java.ext.dirs來決定的,該加載器在加載時不一樣於其餘加載器,
它加載時會搜索指定路徑下的全部子目錄,也就是說它會搜索java.ext.dirs所指定下的全部子目錄下的class文件或jar文件。
同時也能夠用參數-Djava.ext.dirs來改變它的搜索路徑。
System.getProperty("java.ext.dirs").split(";");
D:\tools\Java\jdk1.7.0_17\jre\lib\ext
C:\Windows\Sun\Java\lib\ext
AppClassLoader也稱SystemClassLoader, 它的搜索路徑是由java.class.path來指定的,
注意:AppClassLoader不會搜索java.class.path下的子目錄的,因此在在加載子目錄中的
資源文件時要指定相對目錄,如最開始的那個例子。
System.getProperty("java.class.path").split(";");
E:\core_wkspace\TestProject\bin
E:\core_wkspace\callProcedure\bin
E:\core_wkspace\callProcedure\lib\c3p0-0.9.1.2.jar
E:\core_wkspace\callProcedure\lib\commons-io-2.4.jar
E:\core_wkspace\callProcedure\lib\dom4j-1.6.1.jar
E:\core_wkspace\callProcedure\lib\fastjson-1.1.37.jar
E:\core_wkspace\callProcedure\lib\log4j-1.2.17.jar
E:\core_wkspace\callProcedure\lib\log4j-api-2.1.jar
E:\core_wkspace\callProcedure\lib\log4j-core-2.1.jar
E:\core_wkspace\callProcedure\lib\log4j2Mgr.jar
E:\core_wkspace\callProcedure\lib\ojdbc6-11.1.0.7.jar
關係:
類加載的機制是,全盤負責委託機制,全盤負責即若是AppCalssLoader要加載一個類文件,除非顯示指定另外一個加載器,否則
這個類文件以及此文件所依賴和引用的類,都由AppClassLoader負責加載。 委託即AppClassLoader若是沒有加載過String類,
就先委託父類加載器ExtClassLoader加載String類,(由委託機制ExtClassLoader委託BootStrapLoader加載String類,String
類在rt.jar中,全部由BootStrapLoader加載String類)。只有在父類加載器找不到字節碼文件的狀況下才從AppClassLoader的類路徑
中查找並裝載目標類(如上面的TestProject工程中的TestSendHttp.class)