tomcat 是如何做到不同webapp 类隔离的

Posted kevin7234

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tomcat 是如何做到不同webapp 类隔离的相关的知识,希望对你有一定的参考价值。

 这个问题的核心是classloader 

 

技术图片

上图中 启动类加载器,扩展类加载器,应用程序类加载器是 jvm 自带的类加载器.

 

comm  catalina  shared webapp 是tomcat 扩展的加载器,他们分别加载 /common/*/server/*/shared/*

WebAppClassLoader 负载加载  webapp 目录的jar 和 class .

WebAppClassLoader  没有遵循双亲委托模式,他的具体加载逻辑如下:

技术图片

 

第1步:检查当前class loader 的缓存resourceEntries,是否已经加载,如果有直接返回。

第2步:检查 jvm 自带加载器是否加载过。

第3步:尝试用  javaseClassLoader 去加载,为什么要做这个尝试呢,防止代码重写了java.lang.String  等jdk核心类,从而导致异常。

第4步:如果设置了双亲委托模式 delegateLoad=true ,尝试用父加载器加载。

第5步: 尝试从当前classloader 制定的目录中加载,同时会将加载信息放到缓存中 resourceEntries

这样就实现了资源隔离。

 

扩展信息:

1.通过gc 回收class loader ,从而可以实现回收class,重新创建classloader,然后重新load class ,从而达到不重启jvm更新class的目的(热更新),jsp 的热更新就是这么干的。

技术图片

 

 2. jvm instrumentation 机制可以通过agent,去修改正在运行中的已加载的class 对象,该方法很有用,比如生产环境出了问题,重启后问题无法复现,那么就可以在线增加日志排错.

阿里巴巴基于该原理开发了一个强大在线调试工具: https://github.com/alibaba/arthas

 

3. ClassFileTransformer  利用tranformer 和 class loader 可以实现很多很神奇的功能,比如所有controller 方法第一行打印出请求参数,实现这个目的可以用spring AOP,同时也可以用ClassFileTransformer。

groovy 通过大量的 ClassFileTransformer 修改了很多jdk 核心class 的方法.

技术图片

 

 

相关资源:

1.https://blog.csdn.net/sdmjhca/article/details/77716899

2.https://www.cnblogs.com/aspirant/p/8991830.html  

 

以上是关于tomcat 是如何做到不同webapp 类隔离的的主要内容,如果未能解决你的问题,请参考以下文章

Java - 为什么 Java 中允许多个全类名相同但类加载器不同的类存在?

如何设置不同的上下文以指向 webapps Tomcat/Java 之外的外部目录

maven+tomcat调试下,如何做到不用每次都打包,而是直接启动服务就ok?

如何在tomcat上运行选择的webapp

Day692.Tomcat如何隔离Web应用 -深入拆解 Tomcat & Jetty

25 | Context容器(中):Tomcat如何隔离Web应用?