ClassLoader加載資源時的搜索路徑

先來個例子: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)

相關文章
相關標籤/搜索