Tomcat是如何隔离Web应用的

news2024/11/18 12:41:46

Tomcat通过自定义的类加载器WebAppClassLoader打破了双亲委托机制,目的就是为了优化加载Web应用目录下的类。Tomcat 作为 Servlet 容器,它负责加载我们Servlet 类,此外它还负责加载 Servlet 所依赖的 JAR 包。并且Tomcat 本身也是也是一个 Java 程序,因此它需要加载自己的类和依赖的 JAR 包。Tomcat 自定义了一个类加载器 WebAppClassLoader, 并且给每个 Web 应用创建 一个类加载器实例,每个 Context 容器负责创建和维护一个 WebAppClassLoader 加载器 实例。其实现的原理就是不同的类加载器实例加载的类被认为是不同的类,即使它们的类名 相同(不同类加载器实例加载的类是互相隔离的)

Tomcat是如何隔离Web应用的? Tomcat 自定义了一个类加载器 WebAppClassLoader, 并且给每个 Web 应用创建 一个类加载器实例,每个 Context 容器负责创建和维护一个 WebAppClassLoader 加载器 实例。其实现的原理就是不同的类加载器实例加载的类被认为是不同的类,即使它们的类名 相同(不同类加载器实例加载的类是互相隔离的)

Tomcat 的自定义类加载器 WebAppClassLoader 打破了双亲委托机制,它首先自己 尝试去加载某个类,如果找不到再代理给父类加载器,其目的是优先加载 Web 应用自己定 义的类。具体实现就是重写 ClassLoader 的两个方法:findClass 和 loadClass。 在 findClass 方法里,主要有三个步骤:


1. 先在 Web 应用本地目录下查找要加载的类。
2. 如果没有找到,交给父加载器去查找,它的父加载器就是上面提到的系统类加载器
AppClassLoader。
3. 如何父加载器也没找到这个类,抛出 ClassNotFound 异常。

loadClass 方法稍微复杂一点,主要有六个步骤:

1. 先在本地 Cache 查找该类是否已经加载过,也就是说 Tomcat 的类加载器是否已
经加载过这个类。
2. 如果 Tomcat 类加载器没有加载过这个类,再看看系统类加载器是否加载过。
3. 如果都没有,就让ExtClassLoader去加载,这一步比较关键,目的防止 Web 应用
自己的类覆盖 JRE 的核心类。因为 Tomcat 需要打破双亲委托机制,假如 Web 应用
里自定义了一个叫 Object 的类,如果先加载这个 Object 类,就会覆盖 JRE 里面的
那个 Object 类,这就是为什么 Tomcat 的类加载器会优先尝试用 ExtClassLoader
去加载,因为 ExtClassLoader 会委托给 BootstrapClassLoader 去加载,
BootstrapClassLoader 发现自己已经加载了 Object 类,直接返回给 Tomcat 的类
加载器,这样 Tomcat 的类加载器就不会去加载 Web 应用下的 Object 类了,也就
避免了覆盖 JRE 核心类的问题。

4. 如果 ExtClassLoader 加载器加载失败,也就是说 JRE 核心类中没有这类,那么就
在本地 Web 应用目录下查找并加载。
5. 如果本地目录下没有这个类,说明不是 Web 应用自己定义的类,那么由系统类加
载器去加载。这里请你注意,Web 应用是通过Class.forName调用交给系统类加载
器的,因为Class.forName的默认加载器就是系统类加载器。
6. 如果上述加载过程全部失败,抛出 ClassNotFound 异常。

Tomcat类加载器结构:

Tomcat自定义了多个类加载器,CommonClassLoader、CatalinaClassLoader、 SharedClassLoader和WebappClassLoader则是Tomcat自己定义的类加载器,它们分别 加载/common/、/server/、/shared/和/WebApp/WEB-INF/中的Java类库。

其中 WebApp类加载器和Jsp类加载器通常会存在多个实例,每一个Web应用程序对应一个 WebApp类加载器,每一个JSP文件对应一个Jsp类加载器

CommonClassLoader : Tomcat 通用类加载器, 加载的资源可被 Tomcat 和
所有的 Web 应用程序共同获取
CatalinaClassLoader : Tomcat 类加载器, 加载的资源只能被 Tomcat 获取(但
所有 WebappClassLoader 不能获取到 catalinaLoader 加载的类)
SharedClassLoader : Tomcat 各个Context的父加载器, 这个类是所有
WebappClassLoader 的父类, sharedLoader 所加载的类将被所有的
WebappClassLoader 共享获取
WebappClassLoader : 每个Context 对应一个 WebappClassloader, 主要用
于加载 WEB-INF/lib 与 WEB-INF/classes 下面的资源

在 JVM 的实现中有一条隐含的规则,默认情况下,如果一个类由类加载器 A 加载,那 么这个类的依赖类也是由相同的类加载器加载。比如 Spring 作为一个 Bean 工厂,它需要 创建业务类的实例,并且在创建业务类实例之前需要加载这些类。 思考:如果spring作为共享第三方jar包,交给SharedClassLoader加载,但是业务类 在web目录下,不在SharedClassLoader的加载路径下,那spring如何加载web应用目录下 的业务bean呢? Tomcat 为每个 Web 应用创建一个 WebAppClassLoarder 类加载器,并在启动 Web 应用的线程里设置线程上下文加载器,这样 Spring 在启动时就将线程上下文加载器 取出来,用来加载 Bean。

线程上下文加载器是一种类加载器传递机制,因为这个类加载器保存在线程私有数据 里,只要是同一个线程,一旦设置了线程上下文加载器,在线程后续执行过程中就能把这个 类加载器取出来用。

Thread.currentThread().getContextClassLoader()

线程上下文加载器不仅仅可以用在 Tomcat 和 Spring 类加载的场景里,核心框架类需 要加载具体实现类时都可以用到它,比如我们熟悉的 JDBC 就是通过上下文类加载器来加载 不同的数据库驱动的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/348630.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

petalinux 2020.2 离线编译

链接:[https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/embedded-design-tools.html] 2、在ubuntu下安装必要运行库。 1、sudo apt-get install iproute2 gawk python3 python 2、sudo apt-get install build-essential gcc gi…

第七届蓝桥杯省赛——8冰雹数(递归)

题目:任意给定一个正整数N,如果是偶数,执行: N / 2如果是奇数,执行: N * 3 1生成的新的数字再执行同样的动作,循环往复。通过观察发现,这个数字会一会儿上升到很高,一会…

海外问卷调查怎么做?手把手教会你如何薅老外的羊毛

问卷调查相信大家都不陌生。许多组织在推出新项目或新产品之前,会对全社会进行问卷调查,调查消费者或受众对产品的期望和价格的接受范围。东哥今天给大家介绍的就是海外问卷调查项目,外国人的羊毛,带你们薅定了!参与海…

基于ArgoCD实现k8s环境下的持续部署

什么是 argo CD Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes. Argo CD是一个基于Kubernetes的声明式的GitOps工具。 这里我们引入了一个新的概念, 什么是GitOps GitOps是以Git为基础,使用CI/CD来更新运行在云原生环境…

电脑资料如何转移到新电脑?教你3种数据迁移技巧

当下,电脑越来越普及,更换频率也越来越高。当我们购买新电脑,需要将旧电脑上的文件资料迁移到新电脑上,方便使用,电脑资料如何转移到新电脑?其实我们完全可以自己解决哦,下面一起来看下电脑资料…

VMware 修复了三个身份认证绕过漏洞

Bleeping Computer 网站披露,VMware 近期发布了安全更新,以解决 Workspace ONE Assist 解决方案中的三个严重漏洞,分别追踪为 CVE-2022-31685(认证绕过)、CVE-2022-31686 (认证方法失败)和 CVE-…

python应用之小麦生育期气象因子计算——基于pandas库

背景 本次介绍一下python的pandas包操作Excel(或者CSV等),应用情景是计算不同站点小麦多年生育期内的气象因子的特征(积温、降雨、辐射等) 主要涉及以下知识点: 儒略日转换数据框值获取与字符串加法基于que…

.md文件转.pdf文件

一、安装VS code vscode是一个轻量级的、可扩展性十分强的开发编辑器。过程略,比较简单。 二、安装插件Markdown PDF 直接 install 就可以了。 我这里出现了安装失败的情景,这时候可以通过它给的提示,安转markdown-pdf 的 .vsix 文件&#…

数据分析与SAS学习笔记2

SAS在企业使用的情况: SAS是一个很昂贵的商业软件。在企业中使用SAS比较多,在企业界中是比较流行,在学术界使用R比较多。 SAS简介:统计分析系统 处理生物分析数据。 SAS成为统计领域的国际标准软件,服务全球50000多家…

顶象业务安全大讲堂全新升级,挖洞大神喊你来get 挖洞秘籍啦!

CSDN直播间: 红队外网打点与情报收集策略——「业务安全大讲堂第二季第1期」https://live.csdn.net/room/dingxiangtech/rBN4xrOp 顶象业务安全大讲堂第二季将于2月23日重磅回归,本季业务安全大讲堂继续以业务安全为主题,为大家带来业务安全…

网络渗透之信息搜集

网络渗透之信息搜集一、信息搜集1.1 概念1.2 分类1.3 收集那些信息二、域名信息收集2.1 域名介绍2.2 域名分类2.3 域名信息查询- whois2.3.1 whois2.3.2 whois查询2.3.3 whois查询方法2.4 域名信息收集-备案信息三、子域名信息收集四、IP地址信息收集4.1 IP反查域名4.2 域名查询…

UVa 1343 The Rotation Game 旋转游戏 IDA* BFS 路径还原

题目链接:The Rotation Game 题目描述: 给定二十四个整数,这二十四个整数由八个一,八个二,八个三组成,从左到右,从上到下依次描述下图方格中的数字: 例如上图左边对应的输入就是[1,…

Java中List排序的3种方法!

引用:https://blog.csdn.net/sinat_32849897/article/details/122098256 在某些特殊的场景下,我们需要在 Java 程序中对 List 集合进行排序操作。比如从第三方接口中获取所有用户的列表,但列表默认是以用户编号从小到大进行排序的&#xff0c…

acwing 2 普通背包 2维做法的坑

背包问题应该都挺熟了,但还是放一下题目 无论是一维还是二维的解法,思路都比较一致,就是用一个二维的dpdpdp矩阵,dp[i][j]dp[i][j]dp[i][j] 的定义为前 iii 个元素的最优组合在容量为 jjj 的背包的最大价值。 这个定义非常的巧妙…

前缀和-蓝桥杯

一、前缀和的概念数组a[0]~ a[n-1],前缀和sum[i]等于a[0] ~ a[i]的和:sum[0] a[0]sum[1] a[0] a[1]sum[2] a[0] a[1] a[2] ......在O(n)时间内求所有前缀和: sum[i] sum[i-l] a[i]a[0]一般不用。二、前缀和与区间问题预计算出前缀和,能快速计算出区…

C语言结构体(初阶)声明、初始化、成员访问、传参

目录结构体类型的声明结构体变量的定义和初始化结构体成员访问结构体传参1.结构体类型的声明//1. struct Book {char name[20];int price; //成员列表 }b3,b4,b5;//全局变量 int main() {struct Book b1;//b1,b2局部变量struct Book b2;return 0; }//2. struct Book {char n…

重磅!ChatGPT席卷全球,Salesforce将推出EinsteinGPT!

2月9日,Salesforce首席执行官Marc Benioff在Twitter上发布了这样一则推文,表示将于3月7日的TrailblazerDX 23上发布Salesforce EinsteinGPT,随后Salesforce的官方Twitter也进行了转发。 虽然还没有正式的新闻稿,但不少业内人士猜测…

C++【模板初阶】

✨个人主页: Yohifo 🎉所属专栏: C修行之路 🎊每篇一句: 图片来源 No one saves us but ourselves, no one can and no one may. We ourselves must walk the path. 除了我们自己,没有人能拯救我们&#xf…

FreeRTOS-Tickless低功耗模式 | FreeRTOS十四

目录 说明: 一、低功耗模式简介 1.1、STM32低功耗模式 二、Tickless模式 2.1、Tickless模式如何功耗 2.2、Tickless模式设计思想 2.3、为了降低功耗,又不影响系统运行,怎么能做到呢? 三、Tickless模式修改配置 3.1、配置…

如何提升 ETF 期权隐含波动率和希腊值的计算速度?

期权的隐含波动率可以反应市场对未来的预期,通常使用牛顿法和二分法来计算。这两种方法都需要频繁迭代,且迭代次数不能确定,核心代码无法向量化,因此只能通过循环来逼近求解。这就导致在期权相关计算中,隐含波动率往往…