欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Tomcat 类加载过程

程序员文章站 2022-04-03 10:05:30
...
以下内容部分来自网络,如有侵权,请站内联系。

Tomcat 下的工程,使用 WebappClassLoader 进行类的加载。查看 WebappClassLoader 源码,可以总结出 Tomcat 的类加载过程如下:
1. 先在自己(即当前 WebappClassLoader)的缓存中查找,有则返回,无则继续;
2. 再递归地在 parent 的缓存中查找,有则返回,无则继续;
3. 缓存中没有。尝试使用 sun.misc.Launcher$AppClassLoader 加载,成功则返回,失败则继续;
这样做的目的是,避免工程中重写了 Java 基础类,造成混乱。换句话说, webapp 下的 java.lang.* 等将被委托给上层的类加载器( ExtClassLoader 或 LaunchClassLoader 等)加载,这样就保证了基础类的安全。请放心,这里 sun.misc.Launcher$AppClassLoader 是不会加载到 webapp 中用户自定义的类的:我们知道 sun.misc.Launcher$AppClassLoader 是用来加载 classpath 中的类的,但 tomcat 消除了 classpath 的概念。
4. 一般情况下,调用自己的 findClass() 方法进行加载,成功则返回,失败则继续;
5. 若自己加载失败,递归请求 parent 进行加载;
6. 若最终都没能加载成功,则抛出 ClassNotFoundException 。

从4、5两步可以看出, Tomcat 的类加载过程和 Java 经典的类加载策略是有出入的,它在一定程度上破坏了双亲委派模型。这样做的目的是为了迎合 Servlet 规范,应用程序类的优先级要高于容器中类的优先级。

一个 WebappClassLoader 对应着一个 Web 应用程序,其父亲是 Tomcat 的 lib 的类加载器。所以 Tomcat 在默认情况下,不是完全按照先 Tomcat 的 lib 再 Web 应用的 lib 这种顺序去加载类的,正确的 Jar 包加载顺序是:
1. JRE 中的 Java 基础包;
2. Web 应用 WEB-INF\lib 下的包;
3. Tomcat\lib 下的包。
所以,如果想在 Web 应用间共享一些 Jar 包,不仅需要将公共包放在 Tomcat 的 lib 下,还要删掉 Web 应用 lib 下的包,否则 Tomcat 启动时还是会优先加载 Web 应用 lib 下的包的。
相关标签: Tomcat Class Loader