Tomcat的类加载器

一.Jvm的类加载器

Tomcat的类加载器
  1. Bootstrap:用于加载JVM提供的基础运行类,即位于%JAVA_HOME%/jre/lib目录下的核心类库。
  2. Extension: Java提供的一个标准的扩展机制用于加载除核心类库外的Jar包, 即只要复制到指定的扩展目录(可以多个)下的Jar,JVM会自动加载(不需要通过-classpath指定)。默认的扩展目录是%JAVA_HOME%/jre/lib/ext。典型的应用场景就是,Java使用该类加载器加载JVM默认提供的但是不属于核心类库的Jar,如JCE R等。不推荐将应用程序依赖的类库放置到扩展目录下,因为该目录下的类库对所有基于该JVM运行的应用程序可见。
  3. System(AppClassLoader):用于加载环境变量CLASSPATH(不推荐使用)指定目录下的或者-classpath运行参数指定的Jar包。System类加载器通常用于加载应用程序Jar包及其启动人口类(Tomcat的Bootstrap类即由System类加载器加载)。

二.Tomcat的类加载器

官方文档

Tomcat的类加载器
  1. Common:以System为父类加载器,是位于Tomcat应用服务器顶层的公用类加载器。其路径为common.loader,默认指向$CATALINA_HOME/lib下的包。
  2. Catalina: 以Common为父加载器,是用于加载Tomcat应用服务器的类加载器,其路径为server.loader,默认为空。此时Tomcat使用Common类加载器加载应用服务器。
  3. Shared:以Common为父加载器,是所有Web应用的父加载器其路径为shared.loader ,默认为空。此时Tomcat使用Common类加载器作为Web应用的父加载器。
  4. Web应用:以Shared为父加载器,加载/WEB-INF/classes目录下的未压缩的Class和资源文件以及/WEB-INF/lib目录下的Jar包。如前所述,该类加载器只对当前Web应用可见,对其他Web应用均不可见。

从Web应用程序的角度来看,类或资源的加载按以下顺序查找以下存储库

  • Bootstrap classes of your JVM
  • /WEB-INF/classes of your web application
  • /WEB-INF/lib/*.jar of your web application
  • System class loader classes (described above)
  • Common class loader classes (described above)

三.Tomcat类加载器这样设计的优点

应用服务器通常会自行创建类加载器以实现更灵活的控制,这一方面是对规范的实现(Servlet规范要求每个Web应用都有一个独立的类加载器实例),另一方面也有架构层面的考虑。

  1. 隔离性: Web应用类库相互隔离,避免依赖库或者应用包相互影响。设想一下,如果我们有两个Web应用,一个采用了Spring2.5,一个采用了Spring 4.0,而应用服务器使用一个类加载器加载,那么Web应用将会由于Jar包覆盖而导致无法启动成功。
  2. 灵活性:既然Web应用之间的类加载器相互独立,那么我们就能只针对一个Web应用进行重新部署,此时该Web应用的类加载器将会重新创建,而且不会影响其他Web应用。如果采用一个类加载器,显然无法实现,因为只有一个类加载器的时候,类之间的依赖是杂乱无章的,无法完整地移除某个Web应用的类。
  3. 性能:由于每个Web应用都有一个类加载器,因此Web应用在加载类时,不会搜索其他 Web应用包含的Jar包,性能自然高于应用服务器只有一个类加载器的情况。

四.Tomcat类加载器的实现

Bootstrap:initClassLoaders();

  1. commonLoader = createClassLoader(“common”, null);
  2. catalinaLoader = createClassLoader(“server”, commonLoader);
  3. sharedLoader = createClassLoader(“shared”, commonLoader);

digester的创建:

  1. Catalina:createStartDigester();
  2. Digester digester = new Digester();

创建类的过程:

  1. ObjectCreateRule:begin();
  2. Class clazz = digester.getClassLoader().loadClass(realClassName);
  3. SetNextRule:end();
  4. IntrospectionUtils.callMethod1(parent, methodName,child, paramType, digester.getClassLoader());
  5. digester.getClassLoader();
  6. Thread.currentThread().getContextClassLoader();

Original: https://www.cnblogs.com/xysgo/p/16619296.html
Author: 菜阿
Title: Tomcat的类加载器

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/601512/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球