国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Tomcat打破雙親委派機(jī)制實(shí)現(xiàn)隔離Web應(yīng)用的方法

瀏覽:146日期:2023-03-19 16:51:47
目錄
  • Tomcat類(lèi)加載器的層次結(jié)構(gòu)
    • WebAppClassLoader
    • SharedClassLoader
    • CatalinaClassLoader
    • CommonClassLoader
  • Spring的加載問(wèn)題
    • 線程上下文加載器
      • 總結(jié)

        Tomcat通過(guò)自定義類(lèi)加載器WebAppClassLoader打破雙親委派,即重寫(xiě)了JVM的類(lèi)加載器ClassLoader的findClass方法和loadClass方法,以?xún)?yōu)先加載Web應(yīng)用目錄下的類(lèi)。

        Tomcat負(fù)責(zé)加載我們的Servlet類(lèi)、加載Servlet所依賴(lài)的JAR包。Tomcat本身也是個(gè)Java程序,因此它需要加載自己的類(lèi)和依賴(lài)的JAR包。

        若在Tomcat運(yùn)行兩個(gè)Web應(yīng)用程序,它們有功能不同的同名Servlet,Tomcat需同時(shí)加載和管理這兩個(gè)同名的Servlet類(lèi),保證它們不會(huì)沖突。所以Web應(yīng)用之間的類(lèi)需要隔離

        若兩個(gè)Web應(yīng)用都依賴(lài)同一三方j(luò)ar,比如Spring,則Spring jar被加載到內(nèi)存后,Tomcat要保證這兩個(gè)Web應(yīng)用能共享之,即Spring jar只被加載一次,否則隨著三方j(luò)ar增多,JVM的內(nèi)存會(huì)占用過(guò)大。
        所以,和 JVM 一樣,需要隔離Tomcat本身的類(lèi)和Web應(yīng)用的類(lèi)。

        Tomcat類(lèi)加載器的層次結(jié)構(gòu)

        Tomcat的類(lèi)加載器層次結(jié)構(gòu)

        前三個(gè)是加載器實(shí)例名,不是類(lèi)名。

        WebAppClassLoader

        若使用JVM默認(rèn)的AppClassLoader加載Web應(yīng)用,AppClassLoader只能加載一個(gè)Servlet類(lèi),在加載第二個(gè)同名Servlet類(lèi)時(shí),AppClassLoader會(huì)返回第一個(gè)Servlet類(lèi)的Class實(shí)例。
        因?yàn)樵贏ppClassLoader眼里,同名Servlet類(lèi)只能被加載一次。

        于是,Tomcat自定義了一個(gè)類(lèi)加載器WebAppClassLoader, 并為每個(gè)Web應(yīng)用創(chuàng)建一個(gè)WebAppClassLoader實(shí)例。

        每個(gè)Web應(yīng)用自己的Java類(lèi)和依賴(lài)的JAR包,分別放在WEB-INF/classesWEB-INF/lib目錄下,都是WebAppClassLoader加載的。

        Context容器組件對(duì)應(yīng)一個(gè)Web應(yīng)用,因此,每個(gè)Context容器創(chuàng)建和維護(hù)一個(gè)WebAppClassLoader加載器實(shí)例。
        不同加載器實(shí)例加載的類(lèi)被認(rèn)為是不同的類(lèi),即使類(lèi)名相同。這就相當(dāng)于在JVM內(nèi)部創(chuàng)建相互隔離的Java類(lèi)空間,每個(gè)Web應(yīng)用都有自己的類(lèi)空間,Web應(yīng)用之間通過(guò)各自的類(lèi)加載器互相隔離。

        SharedClassLoader

        兩個(gè)Web應(yīng)用之間怎么共享庫(kù)類(lèi),并且不能重復(fù)加載相同的類(lèi)?

        雙親委派機(jī)制的各子加載器都能通過(guò)父加載器去加載類(lèi),于是考慮把需共享的類(lèi)放到父加載器的加載路徑。

        應(yīng)用程序即是通過(guò)該方式共享JRE核心類(lèi)。
        Tomcat搞了個(gè)類(lèi)加載器SharedClassLoader,作為WebAppClassLoader的父加載器,以加載Web應(yīng)用之間共享的類(lèi)。

        若WebAppClassLoader未加載到某類(lèi),就委托父加載器SharedClassLoader去加載該類(lèi),SharedClassLoader會(huì)在指定目錄下加載共享類(lèi),之后返回給WebAppClassLoader,即可解決共享問(wèn)題。

        CatalinaClassLoader

        如何隔離Tomcat本身的類(lèi)和Web應(yīng)用的類(lèi)?

        兄弟關(guān)系:兩個(gè)類(lèi)加載器是平行的,它們可能擁有同一父加載器,但兩個(gè)兄弟類(lèi)加載器加載的類(lèi)是隔離的。

        于是,Tomcat搞了CatalinaClassLoader,專(zhuān)門(mén)加載Tomcat自身的類(lèi)。

        問(wèn)題是,當(dāng)Tomcat和各Web應(yīng)用之間需要共享一些類(lèi)時(shí)該怎么辦?

        CommonClassLoader

        共享依舊靠父子關(guān)系。
        再增加個(gè)CommonClassLoader,作為CatalinaClassLoader和SharedClassLoader的父加載器。

        CommonClassLoader能加載的類(lèi)都可被CatalinaClassLoader、SharedClassLoader 使用,而CatalinaClassLoader和SharedClassLoader能加載的類(lèi)則與對(duì)方相互隔離。WebAppClassLoader可以使用SharedClassLoader加載到的類(lèi),但各個(gè)WebAppClassLoader實(shí)例之間相互隔離。

        Spring的加載問(wèn)題

        JVM默認(rèn)情況下,若一個(gè)類(lèi)由類(lèi)加載器A加載,則該類(lèi)的依賴(lài)類(lèi)也由相同的類(lèi)加載器加載。
        比如Spring作為一個(gè)Bean工廠,它需要?jiǎng)?chuàng)建業(yè)務(wù)類(lèi)的實(shí)例,并且在創(chuàng)建業(yè)務(wù)類(lèi)實(shí)例之前需要加載這些類(lèi)。Spring是通過(guò)調(diào)用Class.forName來(lái)加載業(yè)務(wù)類(lèi)的,我們來(lái)看一下forName的源碼:

        public static Class<?> forName(String className) {    Class<?> caller = Reflection.getCallerClass();    return forName0(className, true, ClassLoader.getClassLoader(caller), caller);}

        會(huì)使用調(diào)用者,即Spring的加載器去加載業(yè)務(wù)類(lèi)。

        Web應(yīng)用之間共享的jar可交給SharedClassLoader加載,以避免重復(fù)加載。Spring作為共享的三方j(luò)ar,本身由SharedClassLoader加載,Spring又要去加載業(yè)務(wù)類(lèi),按照前面那條規(guī)則,加載Spring的類(lèi)加載器也會(huì)用來(lái)加載業(yè)務(wù)類(lèi),但是業(yè)務(wù)類(lèi)在Web應(yīng)用目錄下,不在SharedClassLoader的加載路徑下,這該怎么辦呢?

        線程上下文加載器

        于是有了線程上下文加載器,一種類(lèi)加載器傳遞機(jī)制。因?yàn)樵擃?lèi)加載器保存在線程私有數(shù)據(jù)里,只要是同一個(gè)線程,一旦設(shè)置了線程上下文加載器,在線程后續(xù)執(zhí)行過(guò)程中就能把這個(gè)類(lèi)加載器取出來(lái)用。因此Tomcat為每個(gè)Web應(yīng)用創(chuàng)建一個(gè)WebAppClassLoader類(lèi)加載器,并在啟動(dòng)Web應(yīng)用的線程里設(shè)置線程上下文加載器,這樣Spring在啟動(dòng)時(shí)就將線程上下文加載器取出來(lái),用來(lái)加載Bean。Spring取線程上下文加載的代碼如下:

        cl = Thread.currentThread().getContextClassLoader();

        在StandardContext的啟動(dòng)方法,會(huì)將當(dāng)前線程的上下文加載器設(shè)置為WebAppClassLoader。

        啟動(dòng)方法結(jié)束時(shí),會(huì)恢復(fù)線程的上下文加載器:

        Thread.currentThread().setContextClassLoader(originalClassLoader);

        這是為什么呢?

        線程上下文加載器其實(shí)是線程的一個(gè)私有數(shù)據(jù),跟線程綁定,這個(gè)線程完成啟動(dòng)Context組件后,會(huì)被回收到線程池,之后被用來(lái)做其他事情,為了不影響其他事情,需恢復(fù)之前的線程上下文加載器。
        優(yōu)先加載web應(yīng)用的類(lèi),當(dāng)加載完了再改回原來(lái)的。

        線程上下文的加載器就是指定子類(lèi)加載器來(lái)加載具體的某個(gè)橋接類(lèi),比如JDBC的Driver的加載。

        總結(jié)

        Tomcat的Context組件為每個(gè)Web應(yīng)用創(chuàng)建一個(gè)WebAppClassLoader類(lèi)加載器,由于不同類(lèi)加載器實(shí)例加載的類(lèi)是互相隔離的,因此達(dá)到了隔離Web應(yīng)用的目的,同時(shí)通過(guò)CommonClassLoader等父加載器來(lái)共享第三方JAR包。而共享的第三方JAR包怎么加載特定Web應(yīng)用的類(lèi)呢?可以通過(guò)設(shè)置線程上下文加載器來(lái)解決。

        多個(gè)應(yīng)用共享的Java類(lèi)文件和JAR包,分別放在Web容器指定的共享目錄:

        CommonClassLoader
        對(duì)應(yīng) <Tomcat>/common/*

        CatalinaClassLoader
        對(duì)應(yīng) <Tomcat >/server/*

        SharedClassLoader
        對(duì)應(yīng) <Tomcat >/shared/*

        WebAppClassloader
        對(duì)應(yīng) <Tomcat >/webapps/<app>/WEB-INF/*

        可以在Tomcat conf目錄下的Catalina.properties文件里配置各種類(lèi)加載器的加載路徑。

        當(dāng)出現(xiàn)ClassNotFound錯(cuò)誤時(shí),應(yīng)該檢查你的類(lèi)加載器是否正確。
        線程上下文加載器不僅僅可以用在Tomcat和Spring類(lèi)加載的場(chǎng)景里,核心框架類(lèi)需要加載具體實(shí)現(xiàn)類(lèi)時(shí)都可以用到它,比如我們熟悉的JDBC就是通過(guò)上下文類(lèi)加載器來(lái)加載不同的數(shù)據(jù)庫(kù)驅(qū)動(dòng)的。

        到此這篇關(guān)于Tomcat打破雙親委派機(jī)制實(shí)現(xiàn)隔離Web應(yīng)用的方法的文章就介紹到這了,更多相關(guān)Tomcat 隔離Web應(yīng)用內(nèi)容請(qǐng)搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!

        標(biāo)簽: Tomcat
        相關(guān)文章:
        主站蜘蛛池模板: 特级毛片免费视频播放 | 欧美一区三区 | 亚洲图片视频在线 | 视频一区免费 | 午夜在线观看视频免费 成人 | 欧美野外性xxxxfeexxxxx | 男女午夜视频在线观看 | 亚洲欧美第一 | 日本黄网站高清色大全 | 男女午夜 | 在线免费自拍 | 欧美日韩综合网在线观看 | 2022久久免费精品国产72精品 | 国产成人在线小视频 | 视频一区亚洲 | 日本色综合网 | 亚洲欧美一区二区三区综合 | 国产亚洲精品久久麻豆 | 9久9久女女热精品视频免费观看 | 99热精品在线免费观看 | 综合欧美一区二区三区 | 玖草视频在线 | 国产一级精品高清一级毛片 | 手机看成人片 | 免费看a级片 | japanese乱子另类 | 国产欧美一区二区精品久久久 | 国产男女猛烈无遮档免费视频网站 | 国产亚洲综合精品一区二区三区 | 毛片a区| 国产成人精品高清免费 | 成人久久久观看免费毛片 | 偷拍第1页 | 日韩中文字幕免费观看 | 亚洲在线免费视频 | 国产精品短视频免费观看 | 在线免费观看国产视频 | 国产a国产片 | 日韩免费a级在线观看 | 亚洲一区二区三区高清 | 亚洲一区二区三区在线 |