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

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

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

    honzeland

    記錄點(diǎn)滴。。。

    常用鏈接

    統(tǒng)計(jì)

    Famous Websites

    Java

    Linux

    P2P

    最新評(píng)論

    Tomcat ClassLoader and load resources

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

    1 - Tomcat的類載入器的結(jié)構(gòu)
    Tomcat Server在啟動(dòng)的時(shí)候?qū)?gòu)造一個(gè)ClassLoader樹,以保證模塊的類庫是私有的
    Tomcat Server的ClassLoader結(jié)構(gòu)如下:
            +-----------------------------+

            |         Bootstrap           |

            |             |               |

            |          System             |

            |             |               |

            |          Common             |

            |         /      \            |

            |     Catalina  Shared        |

            |               /    \        |

            |          WebApp1  WebApp2   |

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

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

    2 - ClassLoader的工作原理

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

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

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

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

    3 類的查找

    ClassLoader類中l(wèi)oadClass方法為缺省實(shí)現(xiàn),用下面的順序查找類:
    1、調(diào)用findLoadedClass方法來檢查是否已經(jīng)被加載。如果沒有則繼續(xù)下面的步驟。
    2、如果當(dāng)前類裝載器有一個(gè)指定的委托父裝載器,則用委托父裝載器的loadClass方法加載類,也就是委托給父裝載器加載相應(yīng)的類。
    3、如果這個(gè)類裝載器的委托層級(jí)體系沒有一個(gè)類裝載器加載該類,則使用類裝載器定位類的特定實(shí)現(xiàn)機(jī)制,調(diào)用findClass方法來查找類。

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

    Tomcat Server線程的起點(diǎn)
    構(gòu)造ClassLoader樹,通過Thread.currentThread().setContextClassLoader(catalinaLoader)設(shè)置當(dāng)前的classloader為catalinaLoader。
    載入若干類,然后轉(zhuǎn)入org.apache.catalina.startup.Catalina類中

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

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

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

    (1) If a system class, use system class loader通過系統(tǒng)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 默認(rèn)使用代理裝載器

    [查看代碼]

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

    根據(jù)設(shè)置創(chuàng)建并返回StandardClassLoader的實(shí)例

    [查看代碼]

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

    類載入器

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

    該類僅包含一個(gè)靜態(tài)方法,用來為catalinaLoader載入一些類

    [查看代碼]

    Appendix - 參考

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

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

    [2] 深入Java2平臺(tái)安全

    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 閱讀(857) 評(píng)論(0)  編輯  收藏 所屬分類: Java

    主站蜘蛛池模板: 人妻丰满熟妇无码区免费| 好吊妞在线成人免费| 亚洲AV成人无码天堂| 国产a不卡片精品免费观看| 你懂的免费在线观看| 亚洲一区二区三区深夜天堂| 免费大黄网站在线看| 久久免费公开视频| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 亚洲卡一卡2卡三卡4卡无卡三| 无码国产精品一区二区免费| 一级做a爱过程免费视频高清| 久久亚洲免费视频| 国产成人3p视频免费观看| 精品国产免费一区二区三区香蕉 | 久久国产精品亚洲综合| 天天天欲色欲色WWW免费| a级毛片在线视频免费观看 | 91精品国产免费入口| 国产成人亚洲精品蜜芽影院| 亚洲日本一区二区三区| 国产一区二区三区免费在线观看 | 91麻豆国产免费观看| 少妇亚洲免费精品| 亚洲六月丁香婷婷综合| 国产l精品国产亚洲区在线观看| 免费看片免费播放| 777爽死你无码免费看一二区| 人人爽人人爽人人片A免费 | 亚洲精品无码久久久久YW| 亚洲嫩草影院久久精品| 精品亚洲视频在线观看| 日本人的色道www免费一区| 久久WWW免费人成一看片| 三年片免费观看大全国语| 国产精品无码亚洲一区二区三区| 亚洲精品国产第1页| 国产A在亚洲线播放| 亚洲日本在线观看视频| 日韩免费无码一区二区视频| 四虎在线成人免费网站|