Tomcat类加载架构
前言
主流的Java Web服务器(Tomcat、Jetty、WebLogic、WebSphere等)都有多个自定义的类加载器以及具备的类加载优势,本篇博文主要是通过以Tomcat为例简单认识Java Web服务器具有的特点、以及自定义类加载器是如何实现的。此外,本篇博文主要是根据Tomcat 5.x类加载架构编写的。
主要参考资料《深入理解Java虚拟机》
1、Web服务器需要解决的问题
一个功能健全的Web服务器,都需要解决如下几个问题:
(1)同一个服务器上的两个Web程序所使用的Java类库实现相互独立隔离:不能一个类库在同一个服务器上只有一份却被多个程序使用。
(2)同一个服务器上的两个Web应用程序所使用的Java类库可以被共享:如果不能共享的话,虚拟机内部的Method Area 可能会出现过度膨胀现象。
(3)服务器的类库要与Web应用程序的类库相互隔离,互不影响(即服务器不收Web程序的影响):很多服务器可能是用Java来实现,自然就得使用一些只属于自己的类库。
(4)支持JSP的热替换(HotSwap):大部分主流服务器(WebLogic除外)修改JSP文件都不需要重启服务器。
试想一下,如果上述的4点中任何一点不能满足,特别是(1)-(3)点,那么整个Java Web服务器都是“混乱”的,或者说是不健全的。
2、Tomcat类库存放目录
既然要满足以上四点基本要求,那么当部署一个Web应用时,一个Classpath路径目录是无法满足需求的,通常会提供多个Classpath(一般以classes/lib命名)路径目录,而目录中都会有一个相应的自定义类加载器去加载里面的Java类。在Tomcat中就有三组目录,分别是:/common/*、/server/*、/shared/*;
但值得强调的是在Tomcat 6.x之后这三组目录就不存在了,只有一个总的/lib目录,其他都需要进入配置文件需要时单独配置。所以这里介绍的目录未必能在tomcat安装目录下找到,不过其用意都是一样的;
(1)/common/*:实际创建的时候为/common/lib/目录,可以被Tomcat与所有的Web应用共享的类库都在里面;
但是在Tomcat 6之后/common/lib/目录被废弃,现在默认的是在/lib/下,实际上是将/common、/server、/shared三个目录默认合并到一个/lib目录下。如果不满足具体的业务需求的话,可以在conf/catalina.properties中设置server.loader与shared.loader。打开conf/catalina.properties可以看到:无论是${catalina.base},还是"${catalina.home},都会去找/lib/目录,指定加载的加载器。

CATALINA_BASE:是实例配置位置,也就是一个tomcat可以配置多个实例,实例里面有自己的配置;
CATALINA_HOME:是tomcat安装位置;
common.loader、server.loader、shared.loade:表示tomcat指定自定义的三个加载器。


(2)/server/*:实际创建的时候为/server/lib目录,只能被Tomcat使用的类库。
(3)/shared/*:实际创建的时候为/shared/lib目录,可以被所有的Web应用程序共享使用,但是对Tomcat是不可见的。
(4)/webapps(wtswebapps)/project/WEB-INF/*:实际为/WebApp/project/WEB-INF/lib,是Project独享有的类库。
3、Tomcat自定义加载器
Tomcat自定义的类加载器主要有:ComnonClassLoader、CatalinaClassLoader、SharedClassLoader和WebAppClassLoader四个类加载器。
(1)ComnonClassLoader:加载/common/*目录下的类,但是上述可知现在的指定加载都会在Catalina.properties中配置。
(2)CatalinaClassLoader:加载/server/*目录下的类,同理现在在Catalina.properties中指定配置。
(3)SharedClassLoader:加载/shared/*目录下的类,同理现在在Catalina.properties中指定配置。
(4)WebAppClassLoader:加载/webapps(wtswebapps)/project/WEB-INF/*目录下项目lib中的类。
结合之前三个类加载器(BootstrapClassLoader、ExtensionClassLoader、ApplicationLoader)与Tomcat自定义的四个加载器组合成的委派关系(Tomcat服务器的类加载机构)如下所示:

(注:其中JasperLoader为Jsp类加载器,JSP文件编译后为Class文件,需要加载)
通过此关系图我们可以得到如下两点:
(1)CatalinaClassLoader与SharedClassLoader是相互隔离独立的;
(2)WebAppClassLoader可以使用SharedClassLoader加载类,同理WebAppClassLoader可以代替JspClassLoader加载类,CommonClassLoader加载的类可以被CatalinaClassLoader与SharedClassLoader使用。
同时需要注意还有以下两点:
- JspClassLoader只能加载这个JSP文件所编译出Class文件,当JSP文件被修改时,会替换当前JspClassLoader实例,之后会重新建立一个新的JspClassLoader实例,这也就是HotSwap的内部实现;
- 不同的WebAppClassLoader是相互隔离的;
对于Tomcat 6.x版本,只有在conf/catalina.properties中配置了shared.loader与server.loader才能使用SharedClassLoader与CatalinaClassLoader实例,不然会默认使用ComnonClassLoader的实例来代替;
- 如果默认设置不能满足需要,则可以通过修指定配置文件中的shared.loader与server.loader,之后重新启动Tomcat 5.x加载器架构。
Tomcat类加载架构的更多相关文章
- 服务器 : Apache Tomcat - 理解架构层次
文章概览 相信很多接触java的人都对Tom猫有着多少的熟悉,就个人而言,本来只知道Tom简单的操作与配置,就像裹上一层纱,迷迷糊糊的. Tomcat的书籍本来就不多,高分的还是很久之前的版本,直到最 ...
- Tomcat整体架构分析
下面让我们来看看Tomcat容器的整体结构: 本文的目的是覆盖这张图中所涉及的主要请求处理组件.而上图中的一些高级主题如集群和安全则不是在本文讨论的范围之内. 本图中,Service, Host, C ...
- 深入理解JVM虚拟机7:JNDI,OSGI,Tomcat类加载器实现
打破双亲委派模型 JNDI JNDI 的理解 JNDI是 Java 命名与文件夹接口(Java Naming and Directory Interface),在J2EE规范中是重要的规范之中的一 ...
- java类加载器-Tomcat类加载器
在上文中,已经介绍了系统类加载器以及类加载器的相关机制,还自定制类加载器的方式.接下来就以tomcat6为例看看tomat是如何使用自定制类加载器的.(本介绍是基于tomcat6.0.41,不同版本可 ...
- Tomcat 系统架构与设计模式
Tomcat 系统架构与设计模式,第 1 部分: 工作原理 这个分为两个部分的系列文章将研究 Apache Tomcat 的系统架构以及其运用的很多经典设计模式.本文是第 1 部分,将主要从 Tomc ...
- 图解Tomcat类加载机制
说到本篇的tomcat类加载机制,不得不说翻译学习tomcat的初衷. 之前实习的时候学习javaMelody的源码,但是它是一个Maven的项目,与我们自己的web项目整合后无法直接断点调试.后来同 ...
- Tomcat类加载器机制
Tomcat为什么需要定制自己的ClassLoader: 1.定制特定的规则:隔离webapp,安全考虑,reload热插拔 2.缓存类 3.事先加载 要说Tomcat的Classloader机制,我 ...
- tomcat 系统架构与设计模式 第二部分 设计模式 转
Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析 许 令波, Java 开发工程师, 淘宝网 许令波,现就职于淘宝网,是一名 Java 开发工程师.对大型互联网架构设计颇感兴趣,并对一些 ...
- tomcat 系统架构与设计模式 第一部分 系统架构工作原理 转
Tomcat 系统架构与设计模式,第 1 部分: 工作原理 许 令波, Java 开发工程师, 淘宝网 许令波,现就职于淘宝网,是一名 Java 开发工程师.对大型互联网架构设计颇感兴趣,并对一些开源 ...
随机推荐
- 3、MHC主要组织相容性复合体
主要组织相容性复合体 (major histocompatibility complex MHC) 位于脊椎动物某对染色体上紧密连锁的基因群,其编码的蛋白是主要组织相容性抗原,是移植排斥反应的主要抗原 ...
- sudo -iu [用户] 命令无法正常切换到用户目录的原因
今天干活时遇到一个问题,在sudo -iu [用户]命令执行后无法切换到用户对应的[ 用户@机器 ~$ ]命令行 .bashrc已正常配置为 if [ -f /etc/bashrc ]; then . ...
- Windows服务器开发和Linux服务器软件开发的区别
大型网页游戏服务器开发(Windows+Linux) 进程监听 负载均衡 数据库分发 MapGIS IGServer(Java C++)
- 《Linux就该这么学》
参加了第19期课程的培训,感谢刘老师的辛苦付出,课程讲的很好,真心推荐老刘的这本书真是<Linux就该这么学>!!! 本书是由全国多名红帽架构师(RHCA)基于最新Linux系统共同编写的 ...
- Eigen3安装及注意
执行命令: sudo apt-get install libeigen3-dev 安装后执行以下命令 运行命令: sudo cp -r /usr/include/eigen3/Eigen /usr/i ...
- Linux基础操作命令
一.系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 – (SMBIO ...
- Java的简单类型不能够精确的对浮点数进行运算
由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精确的浮点数运算,包括加减乘除和四舍五入. import java.math.BigDecimal; /** * 由于Java的简单类 ...
- 每天学点SpringCloud(一):使用SpringBoot2.0.3整合SpringCloud
最近开始学习SpringCloud,在此把我学习的过程记录起来,跟大家分享一下,一起学习.想学习SpringCloud的同学赶快上车吧. 本次学习使用得SpringBoot版本为2.0.3.RELEA ...
- itext实现pdf自动定位合同签订
需求 需要实现如下效果(最终效果) 思考 需求方的要求就是实现签订合同,实现方法不限,但过程中又提出需要在签章的过程中把签订日期的文字也打上去,这就有点坑了~ 一开始的想法是想办法定位需要签名的位置, ...
- redis入门知识汇总
1.什么是redis? Redis 是一个基于内存的高性能key-value数据库. 2.Reids的特点 Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库 ...