深入拆解 Tomcat & Jetty
李号双
eBay 技术主管
38890 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 45 讲
开篇词 (1讲)
深入拆解 Tomcat & Jetty
15
15
1.0x
00:00/00:00
登录|注册

25 | Context容器(中):Tomcat如何隔离Web应用?

共享类
隔离Tomcat本身的类
共享第三方JAR包
隔离Web应用的类
线程上下文加载器
CommonClassLoader
CatalinaClassLoader
SharedClassLoader
WebAppClassLoader
隔离Tomcat本身的类和Web应用的类
共享第三方JAR包
隔离Web应用的类
课后思考
Spring的加载问题
类加载器层次结构
设计需求
Tomcat类加载器

该思维导图由 AI 生成,仅供参考

我在专栏上一期提到,Tomcat 通过自定义类加载器 WebAppClassLoader 打破了双亲委托机制,具体来说就是重写了 JVM 的类加载器 ClassLoader 的 findClass 方法和 loadClass 方法,这样做的目的是优先加载 Web 应用目录下的类。除此之外,你觉得 Tomcat 的类加载器还需要完成哪些需求呢?或者说在设计上还需要考虑哪些方面?
我们知道,Tomcat 作为 Servlet 容器,它负责加载我们的 Servlet 类,此外它还负责加载 Servlet 所依赖的 JAR 包。并且 Tomcat 本身也是一个 Java 程序,因此它需要加载自己的类和依赖的 JAR 包。首先让我们思考这一下这几个问题:
假如我们在 Tomcat 中运行了两个 Web 应用程序,两个 Web 应用中有同名的 Servlet,但是功能不同,Tomcat 需要同时加载和管理这两个同名的 Servlet 类,保证它们不会冲突,因此 Web 应用之间的类需要隔离。
假如两个 Web 应用都依赖同一个第三方的 JAR 包,比如 Spring,那 Spring 的 JAR 包被加载到内存后,Tomcat 要保证这两个 Web 应用能够共享,也就是说 Spring 的 JAR 包只被加载一次,否则随着依赖的第三方 JAR 包增多,JVM 的内存会膨胀。
跟 JVM 一样,我们需要隔离 Tomcat 本身的类和 Web 应用的类。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Tomcat通过自定义类加载器WebAppClassLoader打破了双亲委托机制,实现了Web应用的隔离。Tomcat的类加载器层次结构包括WebAppClassLoader、SharedClassLoader、CatalinaClassLoader和CommonClassLoader,通过这些类加载器实现了不同Web应用之间的隔离和共享。另外,文章还介绍了线程上下文加载器的作用,以及在Tomcat中如何设置线程上下文加载器来解决Spring加载业务类的问题。读者需要理解Tomcat类加载器的设计原理,以及Web应用的Java类文件和依赖的JAR包的放置规则。此外,文章还提出了课后思考问题,引发读者对文章内容的深入思考和讨论。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入拆解 Tomcat & Jetty 》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(29)

  • 最新
  • 精选
  • Cy190622
    老师好,您讲个很通透。还有一点问题请教一下: 1.线程上下文的加载器是不是指定子类加载器来加载具体的某个桥接类。比如JDBC的Driver的加载。 2.每个Web下面的java类和jar(WEB-INF/classes和WEB-INF/lib),都是WebAppClassLoader加载吗? 3.Web容器指定的共享目录一般是在什么路径下

    作者回复: 1和2你说的都准确。 CommonClassLoader对应<Tomcat>/common/* CatalinaClassLoader对应 <Tomcat >/server/* SharedClassLoader对应 <Tomcat >/shared/* WebAppClassloader对应 <Tomcat >/webapps/<app>/WEB-INF/*目录

    2019-07-06
    2
    40
  • 王之刚
    最后的问题没有想明白,有人能详细解释一下吗?

    作者回复: 线程上下文加载器其实是线程的一个私有数据,跟线程绑定的,这个线程做完启动Context组件的事情后,会被回收到线程池,之后被用来做其他事情,为了不影响其他事情,需要恢复之前的线程上下文加载器。

    2019-07-06
    5
    37
  • nightmare
    老师,上下文加载器是不是比如说我在加载spring的线程设置为webappclassloader那么就算spring的jar是由shared classloader加载的,那么spring加载的过程中也是由webappclassloader来加载,而用完设置回去,是因为我只需要跨classloader的时候才需要线程上下文加载器

    作者回复: 是的👍

    2019-07-06
    13
  • Li Shunduo
    Tomcat 9中只有这些目录了: conf, logs, bin, lib, temp, work, webapps. 并没有下面这些类加载器对应的common/shared/server目录,是需要自己手工创建吗? CommonClassLoader对应<Tomcat>/common/* CatalinaClassLoader对应 <Tomcat >/server/* SharedClassLoader对应 <Tomcat >/shared/* WebAppClassloader对应 <Tomcat >/webapps/<app>/WEB-INF/*目录

    作者回复: 你可以在Tomcat conf目录下的Catalina.properties文件里配置各种类加载器的加载路径

    2019-07-10
    12
  • 大漠落木
    找不到 CommonClassLoader CatalinaClassLoader SharedClassLoader 这三个类 public class WebappClassLoader extends WebappClassLoaderBase public abstract class WebappClassLoaderBase extends URLClassLoader

    作者回复: 前面三个是加载器实例名,不是类名,你可以在BootStrap.java中找到

    2019-07-06
    11
  • nightmare
    老师我今天做了试验,在tomcat下和conf同级建立shared目录,然后把两个项目的spring的jar包放到shared目录下,然后webapp/class下的spring的jar包删除,启动报找不到spring的jar包,tomcat版本为7.x,是不是还需要配置什么啊,请老师帮忙指导一下

    作者回复: 你可以在Tomcat conf目录下的catalina.properties文件中配置各加载器的加载路径

    2019-07-06
    2
    7
  • 每天一点点
    课后思考题 先切换 WebAppClassLoader 是因为 tomcat 的加载机制,需要先加载 web 的类,然后在共享类等 老师,对么?

    作者回复: 对的

    2019-08-01
    5
  • 清风
    看代码,CommonClassLoader,CatalinaClassLoader,SharedClassLoader引用了同一个对象,这样的话,是怎么做到类空间隔离的呢

    作者回复: 它们是不同的类加载器实例,实例,实例,不同实例的类加载器加载的同名类是不同的

    2019-07-09
    2
    3
  • 一颗苹果
    老师请问下,如果tomcat的不同应用引用了不同版本的spring依赖,sharedClassloader 怎么区分不同版本呢

    作者回复: 这种情况就不是公共类库了,应该放到各Web应用的路径下去

    2019-07-07
    3
  • 业余爱好者
    之前做了一个项目,在tomcat下面部署了两个springboot打的war,这两个war都依赖了同一个数据访问用的jar包,tomcat在启动第二个war项目时,报什么datasource已经实例化的一个错误,导致第二个项目启动失败。后来查了下资料,在application.yml里禁用了jmx解决。 虽然问题解决了,但却不明就里,不知道是不是web应用没有做隔离的缘故。不知道这样理解对不对。。

    作者回复: 应该在Tomcat安装目录下建一个shared目录,把web应用共享的库放这个目录下

    2019-07-06
    2
    3
收起评论
显示
设置
留言
29
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部