<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    honzeland

    記錄點滴。。。

    常用鏈接

    統計

    Famous Websites

    Java

    Linux

    P2P

    最新評論

    Tomcat ClassLoader and load resources

    zz: http://rosonsandy.blogdriver.com/rosonsandy/871539.html

    1 - Tomcat的類載入器的結構
    Tomcat Server在啟動的時候將構造一個ClassLoader樹,以保證模塊的類庫是私有的
    Tomcat Server的ClassLoader結構如下:
            +-----------------------------+

            |         Bootstrap           |

            |             |               |

            |          System             |

            |             |               |

            |          Common             |

            |         /      \            |

            |     Catalina  Shared        |

            |               /    \        |

            |          WebApp1  WebApp2   |

            +-----------------------------+

    其中:
    - Bootstrap - 載入JVM自帶的類和$JAVA_HOME/jre/lib/ext/*.jar
    - System - 載入$CLASSPATH/*.class
    - Common - 載入$CATALINA_HOME/common/...,它們對TOMCAT和所有的WEB APP都可見
    - Catalina - 載入$CATALINA_HOME/server/...,它們僅對TOMCAT可見,對所有的WEB APP都不可見
    - Shared - 載入$CATALINA_HOME/shared/...,它們僅對所有WEB APP可見,對TOMCAT不可見(也不必見)
    - WebApp - 載入ContextBase?/WEB-INF/...,它們僅對該WEB APP可見

    2 - ClassLoader的工作原理

    每個運行中的線程都有一個成員contextClassLoader,用來在運行時動態地載入其它類
    系統默認的contextClassLoader是systemClassLoader,所以一般而言java程序在執行時可以使用JVM自帶的類、$JAVA_HOME/jre/lib/ext/中的類和$CLASSPATH/中的類
    可以使用Thread.currentThread().setContextClassLoader(...);更改當前線程的contextClassLoader,來改變其載入類的行為

    ClassLoader被組織成樹形,一般的工作原理是:
    1) 線程需要用到某個類,于是contextClassLoader被請求來載入該類
    2) contextClassLoader請求它的父ClassLoader來完成該載入請求
    3) 如果父ClassLoader無法載入類,則contextClassLoader試圖自己來載入

    注意:WebApp?ClassLoader的工作原理和上述有少許不同:
    它先試圖自己載入類(在ContextBase?/WEB-INF/...中載入類),如果無法載入,再請求父ClassLoader完成

    由此可得:
    - 對于WEB APP線程,它的contextClassLoader是WebApp?ClassLoader
    - 對于Tomcat Server線程,它的contextClassLoader是CatalinaClassLoader

    3 類的查找

    ClassLoader類中loadClass方法為缺省實現,用下面的順序查找類:
    1、調用findLoadedClass方法來檢查是否已經被加載。如果沒有則繼續下面的步驟。
    2、如果當前類裝載器有一個指定的委托父裝載器,則用委托父裝載器的loadClass方法加載類,也就是委托給父裝載器加載相應的類。
    3、如果這個類裝載器的委托層級體系沒有一個類裝載器加載該類,則使用類裝載器定位類的特定實現機制,調用findClass方法來查找類。

    4 - 部分原代碼分析
    4.1 - org/apache/catalina/startup/Bootstrap.java
    Bootstrap中定義了三個classloader:commonLoader,catalinaLoader,sharedLoader.三者關系如下:
    //注意三個自己定置的ClassLoader的層次關系:
                // systemClassLoader (root)
                //   +--- commonLoader
                //          +--- catalinaLoader
                //          +--- sharedLoader

    Tomcat Server線程的起點
    構造ClassLoader樹,通過Thread.currentThread().setContextClassLoader(catalinaLoader)設置當前的classloader為catalinaLoader。
    載入若干類,然后轉入org.apache.catalina.startup.Catalina類中

    4.2 org.apache.catalina.loader.StandardClassLoader.java

    通過看loadClass這個方法來看tomcat是如何加載類的,順序如下:

    (0) Check our previously loaded class cache查找已經裝載的class
            clazz = findLoadedClass(name);

    (1) If a system class, use system class loader通過系統classloader來裝載class
            ClassLoader loader = system;
                clazz = loader.loadClass(name);

    (2) Delegate to our parent if requested如果有代理則使用父類classloader
                ClassLoader loader = parent;
                if (loader == null)
                    loader = system;
                clazz = loader.loadClass(name);

    (3) Search local repositories 查找本地類池,比如$CATALINA_HOME/server
               clazz = findClass(name);

    (4) Delegate to parent unconditionally 默認使用代理裝載器

    [查看代碼]

    4.3 - org/apache/catalina/startup/ClassLoaderFactory.java

    根據設置創建并返回StandardClassLoader的實例

    [查看代碼]

    4.4 - org/apache/catalina/loader/StandardClassLoader.java

    類載入器

    4.5 - org/apache/catalina/startup/SecurityClassLoad.java

    該類僅包含一個靜態方法,用來為catalinaLoader載入一些類

    [查看代碼]

    Appendix - 參考

    [1] http://jakarta.apache.org/tomcat/中的Tomcat 4.1.x文檔Class Loader HOW-TO

    在一個JVM中可能存在多個ClassLoader,每個ClassLoader擁有自己的NameSpace。一個ClassLoader只能擁有一個class對象類型的實例,但是不同的ClassLoader可能擁有相同的class對象實例,這時可能產生致命的問題。如ClassLoaderA,裝載了類A的類型實例A1,而ClassLoaderB,也裝載了類A的對象實例A2。邏輯上講A1=A2,但是由于A1和A2來自于不同的ClassLoader,它們實際上是完全不同的,如果A中定義了一個靜態變量c,則c在不同的ClassLoader中的值是不同的。

    [2] 深入Java2平臺安全

    zz: http://mail-archives.apache.org/mod_mbox/tomcat-users/200212.mbox/raw/%3c20021204192034.P86616-100000@icarus.apache.org%3e
    try {
        Properties props = new Properties();
        InputStream in = getClass().getResourceAsStream("/conf/db.properties");
        props.load(in);
        ......
        propertie1 = props.getProperty("propertie1");

    The examples already given will find properties files for you just fine whether the file is in a directory structure or inside an archive.  How do you think Java loads classes?  It works out of archives, no? here are some various was to access a properties file ( or any resource, for that matter) in whether the app is deployed as a directory or as a .war file (even inside a .jar file in WEB-INF/lib)....

    1. This will load a file in WEB-INF/classes/conf or any jar file in the classpath with a package of "conf"...
        getClass().getResourceAsStream("/conf/db.properties");
    2. This will load a file relative to the current class.  For instance, if the class is "org.mypackage.MyClass", then the file would be loaded at "org.mypackage.conf.dbproperties".  Note that this is because we didn't prepend "/" to the path.  When that is done, the file is loaded from the root of the current classloader where this loads it relative to the current class...
        getClass().getResourceAsStream("conf/db.properties");
    3. This will find db.properties anywhere in the current classloader as long as it exists in a "conf" package...
        getClass().getClassLoader().getResourceAsStream("conf/db.properties");
    4. This will find the file in a "conf" directory inside the webapp (starting from the root).  This starts looking in the same directory as contains WEB-INF.  When I say "directory", I don't mean "filesystem".  This could be in a .war file as well as in an actual directory on the filesystem...
        getServletContext().getResourceAsStream("/conf/db.properties");
    5. Of course you would probably not want just anyone seeing your db.properties file, so you'd probably want to put in inside WEB-INF of your webapp, so....
        getServletContext().getResourceAsStream("/WEB-INF/conf/db.properties");
    6. If your db.properties exists in another classloader which your app has access to, you can reach it by using:
        Thread.currentThread().getContextClassLoader().getResourceAsStream("conf/db.properties");
    that will act similar to getClass().getClassLoader(), but it can see across all available classloaders where the latter can only see within the classloader that loaded the current class.

    posted on 2008-04-24 15:46 honzeland 閱讀(850) 評論(0)  編輯  收藏 所屬分類: Java

    主站蜘蛛池模板: 亚洲a无码综合a国产av中文| 亚洲精品国产成人中文| 精品久久久久亚洲| 免费无码黄动漫在线观看| 亚洲久悠悠色悠在线播放| 啦啦啦中文在线观看电视剧免费版| 亚洲日韩在线视频| 国产精品久久久久免费a∨| 亚洲va乱码一区二区三区| 欧洲乱码伦视频免费| 91在线亚洲综合在线| 国产麻豆免费观看91| 无套内谢孕妇毛片免费看看| 亚洲国产综合精品中文字幕| 韩国免费a级作爱片无码| 久久精品亚洲一区二区| 成人浮力影院免费看| 亚洲日本在线电影| 亚洲人成人网站在线观看| 成全视频高清免费观看电视剧| 久久亚洲精品无码VA大香大香| 久久久高清免费视频| 亚洲jizzjizz少妇| 综合亚洲伊人午夜网| 香蕉免费一区二区三区| 亚洲小说图区综合在线| 久久久久无码专区亚洲av| 无码人妻丰满熟妇区免费 | 久久久青草青青亚洲国产免观| 黄色网址在线免费| 亚洲人成图片网站| 亚洲av无码天堂一区二区三区| 两个人看的www免费高清| 亚洲一线产区二线产区精华| 亚洲AV日韩精品一区二区三区| 久久免费高清视频| 亚洲av无码偷拍在线观看| 久久精品国产96精品亚洲| 国产成人无码a区在线观看视频免费| 国产日韩在线视频免费播放| 亚洲一区二区三区免费视频|