官网:http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html
Java类加载与Tomcat类加载器层级关系对比

Java ClassLoader:
Bootstrap ClassLoader(加载$JAVA_HOME/jre/lib/目录下核心类库:resources.jar,rt.jar,sunrsasign.jar,jsse.jar,jce.jar,charsets.jar,jfr.jar,以及jre/classes目录下的class)
/|\
| Tomcat ClassLoader:
ExtClassLoader(加载$JAVA_HOME/jre/lib/ext/目下的所有jar) -------- Bootstrap(加载$JAVA_HOME/jre/lib/ext/目录下的所有jar)
/|\ /|\
| |
AppClassLoader(加载应用程序classpath目录下的所有jar和class文件) System(加载$CATALINA_HOME/bin/bootstrap.jar,$CATALINA_BASE/bin/tomcat-juli.jar,$CATALINA_HOME/bin/commons-daemon.jar)
/|\
|
Common(加载$CATALINA_BASE/lib和$CATALINA_HOME/lib下的class,资源和jar文件)
/|\
|
WebAppClassLoader(加载WebApp/WEB-INF/classes,WebApp/WEB-INF/lib)

Java ClassLoader验证:

public class ClassLoaderTest {
public static void main(String[] args) {
ClassLoader appClassLoader = ClassLoaderTest.class.getClassLoader();
ClassLoader extClassLoader = appClassLoader.getParent();
ClassLoader bootstrapClassLoader = extClassLoader.getParent();
System.out.println(appClassLoader);
System.out.println(extClassLoader);
System.out.println(bootstrapClassLoader);
}
}
输出:
sun.misc.Launcher$AppClassLoader@73d16e93
sun.misc.Launcher$ExtClassLoader@15db9742
nul

Tomcat ClassLoader验证:

public class ClassLoaderServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ClassLoader loader = this.getClass().getClassLoader();
while(loader != null) {
System.out.println(loader);
loader = loader.getParent();
}
System.out.println(loader);
}
} 输出:
ParallelWebappClassLoader
  context: test-web
  delegate: false
----------> Parent Classloader:
java.net.URLClassLoader@379619aa java.net.URLClassLoader@379619aa
sun.misc.Launcher$AppClassLoader@764c12b6
sun.misc.Launcher$ExtClassLoader@1a93a7ca
null

跟踪org.apache.catalina.loader.ParallelWebappClassLoader源码发现,org.apache.catalina.loader.WebappClassLoaderBase重写了toString()方法:

@Override
public String toString() { StringBuilder sb = new StringBuilder(this.getClass().getSimpleName());
sb.append("\r\n context: ");
sb.append(getContextName());
sb.append("\r\n delegate: ");
sb.append(delegate);
sb.append("\r\n");
if (this.parent != null) {
sb.append("----------> Parent Classloader:\r\n");
sb.append(this.parent.toString());
sb.append("\r\n");
}
if (this.transformers.size() > 0) {
sb.append("----------> Class file transformers:\r\n");
for (ClassFileTransformer transformer : this.transformers) {
sb.append(transformer).append("\r\n");
}
}
return (sb.toString());
}

也就是说,Tomcat的ClassLoader结构为:

null(JVM Bootstrap ClassLoader)
sun.misc.Launcher$ExtClassLoader@1a93a7ca
sun.misc.Launcher$AppClassLoader@764c12b6
java.net.URLClassLoader@379619aa
org.apache.catalina.loader.ParallelWebappClassLoader

Tomcat Common ClassLoader默认的搜索顺序为:

(1)unpacked classes and resources in $CATALINA_BASE/lib
(2)JAR files in $CATALINA_BASE/lib
(3)unpacked classes and resources in $CATALINA_HOME/lib
(4)JAR files in $CATALINA_HOME/lib

Tomcat classloader类图

总结:
1. Java装载类使用“全盘负责委托机制”。
“全盘负责”是指当一个ClassLoder装载一个类时,除非显示地使用另外一个ClassLoder,否则该类所依赖及引用的类也由这个ClassLoder载入;
“委托机制”是指先委托父类装载器寻找目标类,只有在找不到的情况下才从自己的类路径中查找并装载目标类。
2. Tomcat的WebAppClassLoade默认不使用“委托机制”,查找class和资源的顺序如下:

(1)Bootstrap classes of your JVM
(2)/WEB-INF/classes of your web application
(3)/WEB-INF/lib/*.jar of your web application
(4)System class loader classes
(5)Common class loader classes
If the web application class loader is configured with <Loader delegate="true"/> then the order becomes:
(1)Bootstrap classes of your JVM
(2)System class loader classes
(3)Common class loader classes
(4)/WEB-INF/classes of your web application
(5)/WEB-INF/lib/*.jar of your web application

3. Tomcat中变量CATALINA_BASE和CATALINA_HOME的含义

Throughout the docs, you'll notice there are numerous references to $CATALINA_HOME的含义.
This represents the root of your Tomcat installation. When we say, "This information can be found in your $CATALINA_HOME/README.txt file" we mean to look at the README.txt file at the root of your Tomcat install.
Optionally, Tomcat may be configured for multiple instances by defining $CATALINA_BASE for each instance. If multiple instances are not configured, $CATALINA_BASE is the same as $CATALINA_HOME.

一言以蔽之:如果没有明确设置CATALINA_BASE变量,则CATALINA_BASE与CATALINA_HOME值相同,都是值tomcat安装目录。

【参考】
http://www.hollischuang.com/archives/199 深度分析Java的ClassLoader机制(源码级别)
http://blog.csdn.net/xyang81/article/details/7292380  深入分析Java ClassLoader原理

细说tomcat之类加载器的更多相关文章

  1. Tomcat内核之Tomcat的类加载器

    跟其他主流的Java Web服务器一样,Tomcat也拥有不同的自定义类加载器,达到对各种资源库的控制.一般来说,Java Web服务器需要解决以下四个问题: ①   同一个Web服务器里,各个Web ...

  2. Tomcat的类加载器

    看完了Java类装载器,我们再来看看应用服务器(Tomcat)对类加载器的使用,每个应用服务器都有一套自己的类加载器体系,从而与Java的类加载器区别开以达到自己与应用程序隔离的目的.Tomcat的类 ...

  3. 实战分析Tomcat的类加载器结构(使用Eclipse MAT验证)

    一.前言 在各种Tomcat相关书籍,书上都提到了其类加载器结构: 在Tomcat 7或者8中,共享类和Catalina类加载器在catalina.properties中都是没配置的,请看: 所以,c ...

  4. Java类加载机制与Tomcat类加载器架构

    Java类加载机制 类加载器 虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类.实现这 ...

  5. 还是Tomcat,关于类加载器的趣味实验

    一.前言 类加载器,其实是很复杂一个东西,想等到我完全什么都弄明白了再写出来,估计不太现实...现在只能是知道多少写多少吧. 首先,我提一个问题:在我们自己的servlet中(比如ssm中,contr ...

  6. Tomcat源码分析 (五)----- Tomcat 类加载器

    在研究tomcat 类加载之前,我们复习一下或者说巩固一下java 默认的类加载器.楼主以前对类加载也是懵懵懂懂,借此机会,也好好复习一下. 楼主翻开了神书<深入理解Java虚拟机>第二版 ...

  7. Tomcat 类加载器的实现

    Tomcat 内部定义了多个 ClassLoader,以便应用和容器访问不同存储库中的类和资源,同时达到应用间类隔离的目的.本文首发于公众号:顿悟源码. 1. Java 类加载机制 类加载就是把编译生 ...

  8. Tomcat 类加载器打破双亲委派模型

    我们分为4个部分来探讨: 1. 什么是类加载机制? 2. 什么是双亲委任模型? 3. 如何破坏双亲委任模型? 4. Tomcat 的类加载器是怎么设计的? 我想,在研究tomcat 类加载之前,我们复 ...

  9. 学习Tomcat(六)之类加载器

    通过前面的文章我们知道,Tomcat的请求最终都会交给用户配置的servlet实例来处理.Servlet类是配置在配置文件中的,这就需要类加载器对Servlet类进行加载.Tomcat容器自定义了类加 ...

随机推荐

  1. 计算几何细节梳理&模板

    点击%XZY巨佬 向量的板子 #include<bits/stdc++.h> #define I inline using namespace std; typedef double DB ...

  2. 【CF981F】Round Marriage(二分答案,二分图匹配,Hall定理)

    [CF981F]Round Marriage(二分答案,二分图匹配,Hall定理) 题面 CF 洛谷 题解 很明显需要二分. 二分之后考虑如果判定是否存在完备匹配,考虑\(Hall\)定理. 那么如果 ...

  3. 【BZOJ3716】[PA2014]Muzeum(贪心,网络流)

    [BZOJ3716][PA2014]Muzeum(贪心,网络流) 题面 BZOJ 题解 很明显可以写最大权闭合子图,然后会\(TLE\)成傻逼. 为了方便,就把一个警卫能够看到的范围处理一下(把坐标系 ...

  4. c# double decimal

    两种类型 double范围比decimal大,精度比之低 类型 大致范围 精度 .NET Framework 类型 double ±5.0 × 10−324 到 ±1.7 × 10308 15 到 1 ...

  5. [ZJOI2016]小星星&[SHOI2016]黑暗前的幻想乡(容斥)

    这两道题思路比较像,所以把他们放到一块. [ZJOI2016]小星星 题目描述 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细线连着两颗小星星. ...

  6. P1886 P2216 单调队列模板

    何为单调队列? 单调队列是一个队列(废话) 而且必须同时满足下标单调和值单调两个单调特性. 跟优先队列不同,优先队列直接使用堆(heap)来实现,如何删去特定下标元素?不明. 本人喜欢用单调队列存下标 ...

  7. Java并发编程-阻塞队列(BlockingQueue)的实现原理

    背景:总结JUC下面的阻塞队列的实现,很方便写生产者消费者模式. 常用操作方法 常用的实现类 ArrayBlockingQueue DelayQueue LinkedBlockingQueue Pri ...

  8. js弹出层

    js弹出层 1.div附近显示 <div id="message"></div> $().delay().hide(); 2.遮罩层 表单提交后遮住页面,等 ...

  9. delphi架构

    概要介绍:Object Pascal语言的结构比较特殊,跟C有很大的不同,但是它秉承PASCAL语言的一贯结构化的传统,相信大家很容易就可以了解. 一:Program 单元     一个object  ...

  10. 2017-12-15python全栈9期第二天第六节之三次登陆机会升级版再试试

    #!/user/bin/python# -*- coding:utf-8 -*-#当剩余为0次机会时.询问用户是否再试试.如果同意那就再给三次机会.可一直继续username = 'zd'passwo ...