<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樹,以保證模塊的類庫(kù)是私有的
    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都可見(jiàn)
    - Catalina - 載入$CATALINA_HOME/server/...,它們僅對(duì)TOMCAT可見(jiàn),對(duì)所有的WEB APP都不可見(jiàn)
    - Shared - 載入$CATALINA_HOME/shared/...,它們僅對(duì)所有WEB APP可見(jiàn),對(duì)TOMCAT不可見(jiàn)(也不必見(jiàn))
    - WebApp - 載入ContextBase?/WEB-INF/...,它們僅對(duì)該WEB APP可見(jiàn)

    2 - ClassLoader的工作原理

    每個(gè)運(yùn)行中的線程都有一個(gè)成員contextClassLoader,用來(lái)在運(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,來(lái)改變其載入類的行為

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

    注意:WebApp?ClassLoader的工作原理和上述有少許不同:
    它先試圖自己載入類(在ContextBase?/WEB-INF/...中載入類),如果無(wú)法載入,再請(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方法來(lái)檢查是否已經(jīng)被加載。如果沒(méi)有則繼續(xù)下面的步驟。
    2、如果當(dāng)前類裝載器有一個(gè)指定的委托父裝載器,則用委托父裝載器的loadClass方法加載類,也就是委托給父裝載器加載相應(yīng)的類。
    3、如果這個(gè)類裝載器的委托層級(jí)體系沒(méi)有一個(gè)類裝載器加載該類,則使用類裝載器定位類的特定實(shí)現(xiàn)機(jī)制,調(diào)用findClass方法來(lái)查找類。

    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樹,通過(guò)Thread.currentThread().setContextClassLoader(catalinaLoader)設(shè)置當(dāng)前的classloader為catalinaLoader。
    載入若干類,然后轉(zhuǎn)入org.apache.catalina.startup.Catalina類中

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

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

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

    (1) If a system class, use system class loader通過(guò)系統(tǒng)classloader來(lái)裝載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)方法,用來(lá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)生致命的問(wèn)題。如ClassLoaderA,裝載了類A的類型實(shí)例A1,而ClassLoaderB,也裝載了類A的對(duì)象實(shí)例A2。邏輯上講A1=A2,但是由于A1和A2來(lái)自于不同的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 閱讀(850) 評(píng)論(0)  編輯  收藏 所屬分類: Java

    主站蜘蛛池模板: 亚洲狠狠久久综合一区77777| 天天爽亚洲中文字幕| 日本免费xxxx| 亚洲精品精华液一区二区| 亚洲AV伊人久久青青草原| a毛片久久免费观看| 亚洲免费二区三区| 中文亚洲AV片在线观看不卡| 69视频免费在线观看| 国产精品久久久久久亚洲小说| 亚洲VA成无码人在线观看天堂| 最近中文字幕免费mv视频7| 国产日韩在线视频免费播放| 亚洲毛片无码专区亚洲乱| 亚洲精品tv久久久久久久久久| 日本片免费观看一区二区| 永久免费无码网站在线观看个| 亚洲成A∨人片在线观看无码| 4338×亚洲全国最大色成网站| 成人无码区免费A片视频WWW| 国产一级一毛免费黄片| 亚洲第一第二第三第四第五第六| 亚洲国产精品福利片在线观看| 日本不卡视频免费| 毛片免费全部播放无码| 一级中文字幕乱码免费| 亚洲六月丁香婷婷综合| 亚洲春色在线视频| 亚洲国产成人久久综合野外| 成年女人毛片免费播放人| 久久精品电影免费动漫| 免费视频成人国产精品网站| 国产日本亚洲一区二区三区| 亚洲欧洲在线观看| 亚洲精品无码Av人在线观看国产| 国产免费观看视频| 免费看大美女大黄大色| 成人福利免费视频| 精品国产污污免费网站aⅴ | 久久99精品免费视频| 国产免费牲交视频免费播放 |