电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Tomcat打破雙親委派機制實現隔離Web應用的方法

瀏覽:157日期:2023-03-19 16:51:47
目錄
  • Tomcat類加載器的層次結構
    • WebAppClassLoader
    • SharedClassLoader
    • CatalinaClassLoader
    • CommonClassLoader
  • Spring的加載問題
    • 線程上下文加載器
      • 總結

        Tomcat通過自定義類加載器WebAppClassLoader打破雙親委派,即重寫了JVM的類加載器ClassLoader的findClass方法和loadClass方法,以優先加載Web應用目錄下的類。

        Tomcat負責加載我們的Servlet類、加載Servlet所依賴的JAR包。Tomcat本身也是個Java程序,因此它需要加載自己的類和依賴的JAR包。

        若在Tomcat運行兩個Web應用程序,它們有功能不同的同名Servlet,Tomcat需同時加載和管理這兩個同名的Servlet類,保證它們不會沖突。所以Web應用之間的類需要隔離

        若兩個Web應用都依賴同一三方jar,比如Spring,則Spring jar被加載到內存后,Tomcat要保證這兩個Web應用能共享之,即Spring jar只被加載一次,否則隨著三方jar增多,JVM的內存會占用過大。
        所以,和 JVM 一樣,需要隔離Tomcat本身的類和Web應用的類。

        Tomcat類加載器的層次結構

        Tomcat的類加載器層次結構

        前三個是加載器實例名,不是類名。

        WebAppClassLoader

        若使用JVM默認的AppClassLoader加載Web應用,AppClassLoader只能加載一個Servlet類,在加載第二個同名Servlet類時,AppClassLoader會返回第一個Servlet類的Class實例。
        因為在AppClassLoader眼里,同名Servlet類只能被加載一次。

        于是,Tomcat自定義了一個類加載器WebAppClassLoader, 并為每個Web應用創建一個WebAppClassLoader實例。

        每個Web應用自己的Java類和依賴的JAR包,分別放在WEB-INF/classesWEB-INF/lib目錄下,都是WebAppClassLoader加載的。

        Context容器組件對應一個Web應用,因此,每個Context容器創建和維護一個WebAppClassLoader加載器實例。
        不同加載器實例加載的類被認為是不同的類,即使類名相同。這就相當于在JVM內部創建相互隔離的Java類空間,每個Web應用都有自己的類空間,Web應用之間通過各自的類加載器互相隔離。

        SharedClassLoader

        兩個Web應用之間怎么共享庫類,并且不能重復加載相同的類?

        雙親委派機制的各子加載器都能通過父加載器去加載類,于是考慮把需共享的類放到父加載器的加載路徑。

        應用程序即是通過該方式共享JRE核心類。
        Tomcat搞了個類加載器SharedClassLoader,作為WebAppClassLoader的父加載器,以加載Web應用之間共享的類。

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

        CatalinaClassLoader

        如何隔離Tomcat本身的類和Web應用的類?

        兄弟關系:兩個類加載器是平行的,它們可能擁有同一父加載器,但兩個兄弟類加載器加載的類是隔離的。

        于是,Tomcat搞了CatalinaClassLoader,專門加載Tomcat自身的類。

        問題是,當Tomcat和各Web應用之間需要共享一些類時該怎么辦?

        CommonClassLoader

        共享依舊靠父子關系。
        再增加個CommonClassLoader,作為CatalinaClassLoader和SharedClassLoader的父加載器。

        CommonClassLoader能加載的類都可被CatalinaClassLoader、SharedClassLoader 使用,而CatalinaClassLoader和SharedClassLoader能加載的類則與對方相互隔離。WebAppClassLoader可以使用SharedClassLoader加載到的類,但各個WebAppClassLoader實例之間相互隔離。

        Spring的加載問題

        JVM默認情況下,若一個類由類加載器A加載,則該類的依賴類也由相同的類加載器加載。
        比如Spring作為一個Bean工廠,它需要創建業務類的實例,并且在創建業務類實例之前需要加載這些類。Spring是通過調用Class.forName來加載業務類的,我們來看一下forName的源碼:

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

        會使用調用者,即Spring的加載器去加載業務類。

        Web應用之間共享的jar可交給SharedClassLoader加載,以避免重復加載。Spring作為共享的三方jar,本身由SharedClassLoader加載,Spring又要去加載業務類,按照前面那條規則,加載Spring的類加載器也會用來加載業務類,但是業務類在Web應用目錄下,不在SharedClassLoader的加載路徑下,這該怎么辦呢?

        線程上下文加載器

        于是有了線程上下文加載器,一種類加載器傳遞機制。因為該類加載器保存在線程私有數據里,只要是同一個線程,一旦設置了線程上下文加載器,在線程后續執行過程中就能把這個類加載器取出來用。因此Tomcat為每個Web應用創建一個WebAppClassLoader類加載器,并在啟動Web應用的線程里設置線程上下文加載器,這樣Spring在啟動時就將線程上下文加載器取出來,用來加載Bean。Spring取線程上下文加載的代碼如下:

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

        在StandardContext的啟動方法,會將當前線程的上下文加載器設置為WebAppClassLoader。

        啟動方法結束時,會恢復線程的上下文加載器:

        Thread.currentThread().setContextClassLoader(originalClassLoader);

        這是為什么呢?

        線程上下文加載器其實是線程的一個私有數據,跟線程綁定,這個線程完成啟動Context組件后,會被回收到線程池,之后被用來做其他事情,為了不影響其他事情,需恢復之前的線程上下文加載器。
        優先加載web應用的類,當加載完了再改回原來的。

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

        總結

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

        多個應用共享的Java類文件和JAR包,分別放在Web容器指定的共享目錄:

        CommonClassLoader
        對應 <Tomcat>/common/*

        CatalinaClassLoader
        對應 <Tomcat >/server/*

        SharedClassLoader
        對應 <Tomcat >/shared/*

        WebAppClassloader
        對應 <Tomcat >/webapps/<app>/WEB-INF/*

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

        當出現ClassNotFound錯誤時,應該檢查你的類加載器是否正確。
        線程上下文加載器不僅僅可以用在Tomcat和Spring類加載的場景里,核心框架類需要加載具體實現類時都可以用到它,比如我們熟悉的JDBC就是通過上下文類加載器來加載不同的數據庫驅動的。

        到此這篇關于Tomcat打破雙親委派機制實現隔離Web應用的方法的文章就介紹到這了,更多相關Tomcat 隔離Web應用內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!

        標簽: Tomcat
        相關文章:
        主站蜘蛛池模板: 台湾Apex减速机_APEX行星减速机_台湾精锐减速机厂家代理【现货】-杭州摩森机电 | 江苏全风,高压风机,全风环保风机,全风环形高压风机,防爆高压风机厂家-江苏全风环保科技有限公司(官网) | 南京欧陆电气股份有限公司-风力发电机官网 | 生鲜配送系统-蔬菜食材配送管理系统-连锁餐饮订货配送软件-挪挪生鲜供应链管理软件 | 东莞办公家具厂家直销-美鑫【免费3D效果图】全国办公桌/会议桌定制 | 南昌旅行社_南昌国际旅行社_南昌国旅在线 | 伸缩器_伸缩接头_传力接头-巩义市润达管道设备制造有限公司 | 长沙中央空调维修,中央空调清洗维保,空气能热水工程,价格,公司就找维小保-湖南维小保环保科技有限公司 | 南京泽朗生物科技有限公司-液体饮料代加工_果汁饮料代加工_固体饮料代加工 | 深圳市索富通实业有限公司-可燃气体报警器 | 可燃气体探测器 | 气体检测仪 | 滑石粉,滑石粉厂家,超细滑石粉-莱州圣凯滑石有限公司 | 蜗轮丝杆升降机-螺旋升降机-丝杠升降机厂家-润驰传动 | 水厂自动化|污水处理中控系统|水利信息化|智慧水务|智慧农业-山东德艾自动化科技有限公司 | uv机-uv灯-uvled光固化机-生产厂家-蓝盾机电 | 玉米加工设备,玉米深加工机械,玉米糁加工设备.玉米脱皮制糁机 华豫万通粮机 | 北钻固控设备|石油钻采设备-石油固控设备厂家 | 组织研磨机-高通量组织研磨仪-实验室多样品组织研磨机-东方天净 传递窗_超净|洁净工作台_高效过滤器-传递窗厂家广州梓净公司 | 电磁流量计厂家_涡街流量计厂家_热式气体流量计-青天伟业仪器仪表有限公司 | 中空玻璃生产线,玻璃加工设备,全自动封胶线,铝条折弯机,双组份打胶机,丁基胶/卧式/立式全自动涂布机,玻璃设备-山东昌盛数控设备有限公司 | 分轨 | 上传文件,即刻分离人声和伴奏 | 雷达液位计_超声波风速风向仪_雨量传感器_辐射传感器-山东风途物联网 | 花纹铝板,合金铝卷板,阴极铝板-济南恒诚铝业有限公司 | 密集架-密集柜厂家-智能档案密集架-自动选层柜订做-河北风顺金属制品有限公司 | 日本东丽膜_反渗透膜_RO膜价格_超滤膜_纳滤膜-北京东丽阳光官网 日本细胞免疫疗法_肿瘤免疫治疗_NK细胞疗法 - 免疫密码 | 真空粉体取样阀,电动楔式闸阀,电动针型阀-耐苛尔(上海)自动化仪表有限公司 | MES系统-WMS系统-MES定制开发-制造执行MES解决方案-罗浮云计算 | 锂辉石检测仪器,水泥成分快速分析仪-湘潭宇科分析仪器有限公司 | EPDM密封胶条-EPDM密封垫片-EPDM生产厂家 | 网站优化公司_北京网站优化_抖音短视频代运营_抖音关键词seo优化排名-通则达网络 | 无菌检查集菌仪,微生物限度仪器-苏州长留仪器百科 | 专业生物有机肥造粒机,粉状有机肥生产线,槽式翻堆机厂家-郑州华之强重工科技有限公司 | 防爆大气采样器-防爆粉尘采样器-金属粉尘及其化合物采样器-首页|盐城银河科技有限公司 | 交变/复合盐雾试验箱-高低温冲击试验箱_安奈设备产品供应杭州/江苏南京/安徽马鞍山合肥等全国各地 | 上海冠顶工业设备有限公司-隧道炉,烘箱,UV固化机,涂装设备,高温炉,工业机器人生产厂家 | 杭州代理记账多少钱-注册公司代办-公司注销流程及费用-杭州福道财务管理咨询有限公司 | LOGO设计_品牌设计_VI设计 - 特创易 | 挤出熔体泵_高温熔体泵_熔体出料泵_郑州海科熔体泵有限公司 | pH污水传感器电极,溶解氧电极传感器-上海科蓝仪表科技有限公司 | 重庆网站建设,重庆网站设计,重庆网站制作,重庆seo,重庆做网站,重庆seo,重庆公众号运营,重庆小程序开发 | 别墅图纸超市|别墅设计图纸|农村房屋设计图|农村自建房|别墅设计图纸及效果图大全 | 高铝轻质保温砖_刚玉莫来石砖厂家_轻质耐火砖价格 |