tomcat的类加载机制

tomcat的类加载机制遵循了java类加载机制中经典的双亲委派模型。所以要了解tomcat的类加载机制需要先了解双亲委派模型。

双亲委派模型

java的双亲委派模型如下图所示(组合方式实现继承关系):
在这里插入图片描述
Bootstrap类加载器:负责加载jre/lib下的jar,例如rt.jar是java的核心类库,Object、String、System等常用类都存在于rt.jar中。这个加载器存在于虚拟机中,如果是HotSpot虚拟机,这个类加载器是C++语言编写,如果虚拟机本身就是由纯java语言实现,那就是由java编写。如果想要使用这个加载器,可以使用参数-Xbootclasspath指定加载路径,但boostrap类加载器只会加载虚拟机识别的类库,例如rt.jar,否则即使名字不符合,放在lib中也不会被加载。

Extension类加载器:扩展类加载器,负责加载jre/lib/ext中的jar,或者java.ext.dirs系统变量指定路径的类库。

Application类加载器:负责加载用户类路径上指定的类库,由于ClassLoader的getSystemClassLoader方法的返回值,所以也叫作系统类加载器。

tomcat的类加载器

为什么tomcat要实现自己的类加载器?
tomcat作为一个服务器,在它上面可以部署多个应用。默认情况下是使用1中的应用加载器加载类的,但往往部署的应用都会有多个jar依赖,所以第一点为了解决依赖问题,必须保证每个应用的类库独立。 为什么要保证每个应用的类库相互独立呢? 打个比方,我们都知道连接数据库需要数据库驱动,而数据库驱动的版本要与连接的数据库相对应,否则无法获取连接。 那假设部署在tomcat上的两个应用依赖的数据库驱动版本有很大差异,这样直接使用java的系统类加载器会导致这两个应用有一个无法启动。

a)、要保证部署在tomcat上的每个应用依赖的类库相互独立,不受影响。
b)、由于tomcat是采用java语言编写的,它自身也有类库依赖,为了安全考虑,tomcat使用的类库要与部署的应用的类库相互独立。
c)、有些类库tomcat与部署的应用可以共享,比如说servlet-api,使用maven编写web程序时,servlet-api的范围是provided,表示打包时不打包这个依赖,因为我们都知道服务器已经有这个依赖了。
d)、部署的应用之间的类库可以共享。这听起来好像与第一点相互矛盾,但其实这很合理,类被类加载器加载到虚拟机后,会生成代表该类的class对象存放在永久代区域,这时候如果有大量的应用使用spring来管理,如果spring类库不能共享,那每个应用的spring类库都会被加载一次,将会是很大的资源浪费。

于存在上述问题,tomcat实现了自己的类加载器,不仅仅是tomcat,所有的服务器基本都有或多或少上述所说的问题。

tomcat的类加载器设计

tomcat的类加载器设计如下图所示:
在这里插入图片描述
ps: 其中蓝色的类加载器为tomcat自己实现的类加载器。

Common类加载器:负责加载/common目录的类库,这儿存放的类库可被tomcat以及所有的应用使用。

Catalina类加载器:负责加载/server目录的类库,只能被tomcat使用。

Shared类加载器:负载加载/shared目录的类库,可被所有的web应用使用,但tomcat不可使用。

WebApp类加载器:负载加载单个Web应用下classes目录以及lib目录的类库,只能当前应用使用。

Jsp类加载器:负责加载Jsp,每一个Jsp文件都对应一个Jsp加载器。

Tomcat运行期间,Webapp类加载器与Jsp类加载器个数为复数。通过上图的设计,可以解决掉2.1中的问题。

看到这儿你可以翻出tomcat目录结构查看一下,然后你会发现根本没有common、shared、server目录。这是因为只有在conf目录下的catalina.properties指定了server.loader 以及 share.loader两个属性tomcat才会建立CatalinaClassLoader和SharedClassLoader实例,而默认情况下都没指定,所以CatalinaClassLoader以及SharedClassLoader都会使用CommonClassLoader来代替,所以tomcat6.x以上顺理成章地把上述三个目录合并成了一个lib目录。这个目录相当于/common目录的作用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值