Tomcat打破双亲委派模型的方式

文章目录

1、前言

双亲委派模型是一种类加载机制,它确保了类加载器层次结构中的父加载器先于子加载器尝试加载类。这种机制有助于防止类的重复加载和类之间的不兼容。

然而,为了支持Web应用程序的独立性和隔离性,Tomcat需要在某些情况下打破这一原则。

2、标准的双亲委派模型

在标准的双亲委派模型中,类加载器按以下顺序尝试加载类:

  • Bootstrap ClassLoader:引导类加载器,负责加载Java核心类库($JAVA_HOME/jre/lib)。
  • Extension ClassLoader:扩展类加载器,负责加载Java扩展库($JAVA_HOME/jre/lib/ext)。
  • Application ClassLoader:应用类加载器,负责加载应用程序的类路径(classpath)上的类。

子类加载器在加载类时,先请求父加载器加载,只有当父加载器找不到时,子类加载器才会尝试自己加载。

3、Tomcat的类加载器架构

Tomcat为了支持多个Web应用程序的独立性,设计了一套复杂的类加载器架构,主要包括以下几个类加载器:

  • Bootstrap ClassLoader:加载JVM核心类。
  • System ClassLoader:加载Tomcat自身的类和库(位于$CATALINA_HOME/lib)。
  • Common ClassLoader:加载共享库(位于$CATALINA_HOME/lib)。
  • Webapp ClassLoader:每个Web应用都有自己的类加载器,负责加载Web应用程序的类和库(位于WEB-INF/classes和WEB-INF/lib)。

4、Tomcat打破双亲委派模型的方式

Tomcat通过自定义类加载器的实现,允许Web应用程序在加载类时打破双亲委派模型。这种机制允许Web应用程序优先加载自己的类和库,而不是依赖父加载器。这种行为主要通过WebappClassLoader来实现。

具体实现:

WebappClassLoader:Tomcat为每个Web应用创建一个WebappClassLoader实例。这个类加载器会首先尝试从WEB-INF/classes和WEB-INF/lib中加载类,而不是先委派给父加载器。

双亲委派的打破:

当WebappClassLoader加载类时,它会检查是否在其自己的类路径中存在。如果存在,它会直接加载,而不是委派给父加载器。

这种机制通过在WebappClassLoader的loadClass方法中覆盖默认的双亲委派行为实现。

例如:org.apache.catalina.loader.WebappClassLoaderBase类中的findClass方法实现了优先从Web应用程序的类路径加载类。

示例代码:

以下是WebappClassLoader如何打破双亲委派模型的简化示例:

java 复制代码
public class WebappClassLoader extends URLClassLoader {

    private ClassLoader parent;

    public WebappClassLoader(URL[] urls, ClassLoader parent) {
        super(urls, null); // 将父加载器设置为null
        this.parent = parent;
    }

    @Override
    public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        // 首先,检查是否已经加载了类
        Class<?> clazz = findLoadedClass(name);
        if (clazz == null) {
            try {
                // 尝试从Web应用的类路径中加载类
                clazz = findClass(name);
            } catch (ClassNotFoundException e) {
                // 如果找不到,再委派给父加载器加载
                clazz = parent.loadClass(name);
            }
        }
        if (resolve) {
            resolveClass(clazz);
        }
        return clazz;
    }
}

在这个示例中,WebappClassLoader首先尝试通过findClass方法加载类,如果找不到再委派给父加载器。这种方式打破了双亲委派模型,使得Web应用程序可以优先加载自己的类。

5、总结

Tomcat通过自定义的WebappClassLoader打破了双亲委派模型,允许Web应用程序优先加载自己的类和资源。这种机制确保了每个Web应用程序的独立性和隔离性,避免了类库冲突,并使得每个应用程序可以拥有自己的类和库版本。

相关推荐
希忘auto12 分钟前
详解MySQL安装
java·mysql
冰淇淋烤布蕾24 分钟前
EasyExcel使用
java·开发语言·excel
拾荒的小海螺30 分钟前
JAVA:探索 EasyExcel 的技术指南
java·开发语言
Jakarta EE1 小时前
正确使用primefaces的process和update
java·primefaces·jakarta ee
马剑威(威哥爱编程)1 小时前
哇喔!20种单例模式的实现与变异总结
java·开发语言·单例模式
java—大象1 小时前
基于java+springboot+layui的流浪动物交流信息平台设计实现
java·开发语言·spring boot·layui·课程设计
杨哥带你写代码2 小时前
网上商城系统:Spring Boot框架的实现
java·spring boot·后端
camellias_2 小时前
SpringBoot(二十一)SpringBoot自定义CURL请求类
java·spring boot·后端
布川ku子2 小时前
[2024最新] java八股文实用版(附带原理)---Mysql篇
java·mysql·面试
向阳12182 小时前
JVM 进阶:深入理解与高级调优
java·jvm