一文讲透 Tomcat 的类加载机制!揭秘类加载核心

Posted 架构之美

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一文讲透 Tomcat 的类加载机制!揭秘类加载核心相关的知识,希望对你有一定的参考价值。


-     前言     -


你了解 Apache Tomcat 的类加载机制吗?本文将从底层原理切入,彻底揭秘 Tomcat 类加载所涉及的源码、机制和方案,助你深入掌握 Tomcat 类加载核心!


在啃这篇干货的同时,【文章结尾处】还有玄姐送你的【免费福利】在等你,记得查收哦!


一文讲透 Tomcat 的类加载机制!揭秘类加载核心

-     JVM 类加载器     -


1、JVM类加载器

说起 Tomcat 类加载器,就不得不先简单说一下 JVM 类加载器,如下图所示:


一文讲透 Tomcat 的类加载机制!揭秘类加载核心


  • 启动类加载器:Bootstrap ClassLoader,用于加载JVM提供的基础运行类,即位于%JAVA_HOME%/jre/lib目录下的核 心类库;


  • 扩展类加载器:Extension ClassLoader, Java提供的一个标准的扩展机制用于加载除核心类库外的Jar包,即只要复制 到指定的扩展目录(可以多个)下的Jar, JVM会自动加载(不需要通过-classpath指定)。默认的扩展目录是%JAVA_HOME%加e/lib/ext。典型的应用场景就是,Java使用该类加载 器加载JVM默认提供的但是不属于核心类库的Jar。不推荐将应用程序依赖的 类库放置到扩展目录下,因为该目录下的类库对所有基于该JVM运行的应用程序可见;


  • 应用程序类加载器:Application ClassLoader ,用于加载环境变量CLASSPATH (不推荐使用)指定目录下的或者-classpath运行 参数指定的Jar包。System类加载器通常用于加载应用程序Jar包及其启动入口类(Tomcat 的Bootstrap类即由System类加载器加载)。


这些类加载器的工作原理是一样的,区别是它们的加载路径不同,也就是说 findClass 这个方法查找的路径不同。


双亲委托机制是为了保证一个 Java 类在 JVM 中是唯一的,假如你不小心写了一个与 JRE 核心类同名的类,比如 Object 类,双亲委托机制能保证加载的是 JRE 里的那个 Object 类,而不是你写的 Object 类。


这是因为 AppClassLoader 在加载你的 Object 类时,会委托给 ExtClassLoader 去加载,而 ExtClassLoader 又会委托给 BootstrapClassLoader,BootstrapClassLoader 发现自己已经加载过了 Object 类,会直接返回,不会去加载你写的 Object 类。


这里请注意,类加载器的父子关系不是通过继承来实现的,比如 AppClassLoader 并不是 ExtClassLoader 的子类,而是说 AppClassLoader 的 parent 成员变量指向 ExtClassLoader 对象。同样的道理,如果你要自定义类加载器,不去继承 AppClassLoader,而是继承 ClassLoader 抽象类,再重写 findClass 和 loadClass 方法即可,Tomcat 就是通过自定义类加载器来实现自己的类加载逻辑。不知道你发现没有,如果你要打破双亲委托机制,就需要重写 loadClass 方法,因为 loadClass 的默认实现就是双亲委托机制。


2、类加载器的源码

 
   
   
 


以上是关于一文讲透 Tomcat 的类加载机制!揭秘类加载核心的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat 的类加载机制

一文读懂Java类加载机制

TomcatTomcat的类加载机制

Java和Tomcat类加载机制对比分析

tomcat学习笔记Tomcat类加载机制

tomcat学习笔记Tomcat类加载机制