• Java面试题18-tomcat为什么要使用自定义的类加载器


    一、tomcat类加载器的设计

    Tomcat使用默认的类加载机制行不行 ?

    跟着我的思路思考一下:Tomcat是个web容器,web容器要解决什么问题?

    • 一个web容器可能要部署多个应用程序,不同的应用程序之间可能会依赖同一个第三方库的不同版本,不能要求同一个类库在同一个服务器只有一份,所以tomcat要具有隔离性,每个服务都是独立的。
    • 部署在同一个web容器的多个应用程序的同一个第三方库的版本可能相同,但是不能要求同一版本的类库在每个服务器都有一份,所以tomcat要具有共享性
    • web容器也有自己依赖的类库,不能与应用程序的类库混淆,出于安全性能考虑,应该让容器的类库和程序的类库隔离开来。
    • web容器要支持jsp的修改,因为jsp文件也是要编译成class文件才能在虚拟机中运行,我们要实现热部署的设计,所以web容器应该支持修改jsp之后不用重启。

    二、tomcat使用默认的类加载器行不行

    答案肯定是不行的。
    为什么呢?因为通过我们上面的web容器需要具备的几个特性就知道,如果使用默认的类加载器,是无法实现加载同一类库的不同版本依赖的,默认的类加载器的加载是依据该类的全限定类名的,并且只会加载一个类。

    第二个问题,默认的类加载器是能够实现的,因为他的职责就是保证唯一性。第三个问题和第一个问题一样。我们再看第四个问题,我们想我们要怎么实现jsp文件的热修改,jsp 文件其实也就是class文件,那么如果修改了,但类名还是一样,类加载器会直接取方法区中已经存在的,修改后的jsp是不会重新加载的。

    那么怎么办呢?我们可以直接卸载掉这jsp文件的类加载器,所以你应该想到了,每个jsp文件对应一个唯一的类加载器,当一个jsp文件修改了,就直接卸载这个jsp类加载器。重新创建类加载器,重新加载jsp文件。

    三 、Tomcat 如何实现自己独特的类加载机制?

    在这里插入图片描述

    我们看到,前面3个类加载和默认的一致,CommonClassLoader、CatalinaClassLoader、SharedClassLoader和WebappClassLoader则是Tomcat自己定义的类加载器,它们分别加载*/common/、/server/、/shared/*(在tomcat 6之后已经合并到根目录下的lib目录下)和/WebApp/WEB-INF/*中的Java类库。其中WebApp类加载器和Jsp类加载器通常会存在多个实例,每一个Web应用程序对应一个WebApp类加载器,每一个JSP文件对应一个Jsp类加载器。

    • commonLoader:Tomcat最基本的类加载器,加载路径中的class可以被Tomcat容器本身以及各个Webapp访问;
    • catalinaLoader:Tomcat容器私有的类加载器,加载路径中的class对于Webapp不可见;
    • sharedLoader:各个Webapp共享的类加载器,加载路径中的class对于所有Webapp可见,但是对于Tomcat容器不可见;
    • WebappClassLoader:各个Webapp私有的类加载器,加载路径中的class只对当前Webapp可见;

    从图中的委派关系中可以看出:

    CommonClassLoader能加载的类都可以被Catalina ClassLoader和SharedClassLoader使用,从而实现了公有类库的共用,而CatalinaClassLoader和Shared ClassLoader自己能加载的类则与对方相互隔离。

    WebAppClassLoader可以使用SharedClassLoader加载到的类,但各个WebAppClassLoader实例之间相互隔离。

    而JasperLoader的加载范围仅仅是这个JSP文件所编译出来的那一个.Class文件,它出现的目的就是为了被丢弃:当Web容器检测到JSP文件被修改时,会替换掉目前的JasperLoader的实例,并通过再建立一个新的Jsp类加载器来实现JSP文件的HotSwap功能。

    四、tomcat为什么要自定义三个类加载器

    • commonLoader
    • catalinaLoader
    • sharedLoader

    (1)实现相同jar包不同版本之前的隔离。
    (2)多个服务要共享相同jar包相同版本。
    (3)避免类加载器的内存泄漏。
    (4)服务器自身jar包的依赖与应用程序之间依赖的隔离。
    (5)热部署的设计与实现。

  • 相关阅读:
    勒索软件攻击防护中的6个常见错误
    “元宇宙”最权威的解释来了!全国科技名词委研讨会达成共识
    以makefile的方式在linux上编译代码(小白级别)
    【HCIP】BGP实验
    【Django 04】Serialization 序列化的高级使用
    分析2022年国内国际学校ib的分数
    HTTP协议中Gzip格式的流量分析与识别
    C# StringBuilder 的使用
    React@16.x(28)useMemo
    用HTML+CSS+JS做一个漂亮简单的公司网站(JavaScript期末大作业)
  • 原文地址:https://blog.csdn.net/z318913/article/details/127695088