美文网首页
TOMCAT类加载器架构

TOMCAT类加载器架构

作者: gzss | 来源:发表于2019-08-08 22:22 被阅读0次

主流的Java Web服务器,如tomcat,jetty,weblogic等都实现了自己定义的类加载器(一般都不止一个)。因为一个功能健全的Web服务器,要解决几个问题:

1、部署在同一个服务器上的两个web应用程序所使用的的java类库可以实现相互隔离。比如两个不同的应用程序可能会依赖同一个第三方类库的不同版本,不能要求一个类库在一个服务器中只有一份,服务器应该能够保证两个应用程序的类库可以相互独立使用。

2、部署在同一个服务器上的两个web应用程序所使用的的java类库可以相互共享。比如,用户可能有10个使用spring的应用程序部署在同一台服务器上,如果把10份spring分别放在各应用的隔离目录中,将会是很大的资源浪费,不单单是磁盘空间问题,更重要的是这些spring在使用时都要被加载到服务器内存,如果类库不能共享,虚拟机的放法区就会很容易出现过度膨胀的风险。

3、服务器需要竟可能的保证资深的安全不受部署的web应用程序的影响。

4、支持JSP应用的web服务器,大多数需要支持HotSwap功能。

由于上述问题,再部署web应用时,单独一个ClassPath就无法满足需求了,多以各种web服务器都提供了好几个classpath路径供用户存放第三方类库,这些路径一般以lib或classes命名。被放置在不同路径中的类库,具备不同的访问范围和服务对象,通常,每一个目录都会有一个相应的自定义类加载器去加载放置在里面的java类库。

在tomcat目录结构中,有3组目录(/common/*,/server/*,/shared/*)可以存放java类库,另外还可以加上web应用程序自身的目录WEB-INF/*一共4组,把java类库放置在这些目录的含义如下:
1、放置在/common目录中:类库可以被tomcat和所有的web应用程序共同使用。

2、放置在/server目录中:类库可被tomcat使用,对所有web应用程序都不可见。

3、放置在/shared目录中:类库可被所有web应用共同使用,但对tomcat自己不可见

4、放置在/WEB-INF/目录中:类库仅仅可以被此web应用程序使用,对tomcat和其他web应用程序都不可见。

为了支持这套目录结构,并对目录里面的类库进行加载和隔离,tomcat自定义了多个类加载器,这些类加载器按照经典的双亲委派模型来实现,期关系如图:

Tomcat服务器的类加载架构

灰色背景的三个类加载器是JDK默认提供的类加载器,而CommonClassLoader,CatalinaClassLoader,SharedClassLoader,和WebAppClassLoader则是tomcat自己定义的类加载器,他们分别加载/common/*,/server/*,/shared/*和WEB-INF/*中的java类库,其中WebApp类加载器和JSP类加载器通常会存在多个实例,每一个web应用类加载器通常会对应一个WebApp类加载器,每一个JSP文件对应一个JSP类加载器。

从上图的委派关系中可以看出,CommonClassLoader能加载的类都可以被CatalinaClassLoader和SharedClassLoader使用,而CatalinaClassLoader和SharedClassLoader自己能加载的类则与对方相互隔离。WebAppClassLoader可以使用SharedClassLoader加载到的类,但各个WebAppClassLoader实例之间相互隔离。而JsperLoader的加载范围仅仅是这个JSP文件所编译出来的哪一个class,他出现的目的就是为了被丢弃:当服务器检测到JSP文件被修改时,会替换掉目前的JsperLoader的实例,并通过在建立一个新的Jsp类加载器来实现JSP文件的HotSwap功能。

相关文章

网友评论

      本文标题:TOMCAT类加载器架构

      本文链接:https://www.haomeiwen.com/subject/leofjctx.html