ClassLoader加載資源時的搜索路徑


先來個例子:

    /**
     * 測試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();
        }
    }

 

資源路徑:

不管上面用哪個輸入流,都可以讀取dyan.txt中的auther內容。

結論:

從上面的結果可以看出,AppClassLoader的搜索資源路徑是相對於src的編譯后路徑。

如我的機器src的編譯后路徑是TestProject/bin,則AppClassLoader的搜索資源路徑就包括

E:\core_wkspace\TestProject\bin。

 

類加載器

JVM是通過一個稱為ClassLoader東西來加載Class文件的,每當JVM啟動,

它就會生成三個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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM