自学内容网 自学内容网

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如何打破双亲委派模型的简化示例:

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应用程序的独立性和隔离性,避免了类库冲突,并使得每个应用程序可以拥有自己的类和库版本。


原文地址:https://blog.csdn.net/weixin_47061482/article/details/140286976

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!