tomcat与自定义类加载器

目录

  • 类加载器与类的”相同“判断
    • 类加载器种类
  • 双亲委派的关键源代码
  • JAVA热部署
  • Tomcat独特的类加载机制[^1],[^2]
    • tomcat为什么要使用自定义类加载器?
    • Tomcat如何实现自己独特的类加载机制?
  • 使用自定义类加载器解决JAR包多版本冲突问题[^3]
  • 附:

类加载器与类的”相同“判断

类加载器除了用于加载类外,还可用于确定类在Java虚拟机中的唯一性。
不同类加载器加载的类在 JVM 看来是两个不同的类,因为在 JVM 中一个类的唯一标识是 类加载器+类名(包括包名)。

类加载器种类

启动类加载器,Bootstrap ClassLoader,加载JAVA_HOME\lib,或者被-Xbootclasspath参数限定的类
扩展类加载器,Extension ClassLoader,加载\lib\ext,或者被java.ext.dirs系统变量指定的类
应用程序类加载器,Application ClassLoader,加载ClassPath中的类库
自定义类加载器,通过继承ClassLoader实现,一般是加载我们的自定义类
tomcat与自定义类加载器_第1张图片

双亲委派的关键源代码

JVM 在触发类加载时调用的是 ClassLoader.loadClass 方法。这个方法的实现了双亲委派:先检查指定类(应该仅是包名+类名,不包括类加载器)是否已经被加载过;
若否则递归调用父类加载器的loadClass()方法查询,(父类非指继承,而是指组合的parent变量);
若递归调用失败,就调用本ClassLoader的findClass()进行加载。

我:简单来说,若不想破坏双亲委派,则不要改loadClass()方法,只能改findClass()。

JAVA热部署

首先谈一下何为热部署(hotswap),热部署是在不重启 Java 虚拟机的前提下,能自动侦测到 class 文件的变化,更新运行时 class 的行为。
一种实现的方法是创建自己的 classloader 来加载需要监听的 class,这样就能控制类加载的时机,从而实现热部署:

1、销毁自定义classloader(被该加载器加载的class也会自动卸载);

2、更新class

3、使用新的ClassLoader去加载class

Tomcat独特的类加载机制1,2

tomcat为什么要使用自定义类加载器?

tomcat与自定义类加载器_第2张图片
一个tomcat中可以部署多个应用,而每个应用中都存在很多类,并且各个应用中的类是独立的,全类名是可以相同的,比如一个博客系统中可能存在com.data.User类,一个库存系统中可能也存在com.data.User类。
一个tomcat,不管内部部署了多少应用,Tomcat启动之后就是一个Java进程,也就是一个JVM,所以如果Tomcat中只存在一个类加载器,比如默认的AppClassLoader,那么就只能加载一com.data.User类,这是有问题的 .

Tomcat如何实现自己独特的类加载机制?

Tomcat有多种类加载器。其中WebApp类加载器和Jsp类加载器通常会存在多个实例,每一个Web应用程序对应一个WebApp类加载器,每一个JSP文件对应一个Jsp类加载器:
WebappClassLoader是各个Webapp私有的类加载器,加载路径中的class只对当前Webapp可见。WebAppClassLoader可以使用SharedClassLoader加载到的类,但各个WebAppClassLoader实例之间相互隔离。
而JasperLoader的加载范围仅仅是这个JSP文件所编译出来的那一个.Class文件,它出现的目的就是为了被丢弃:当Web容器检测到JSP文件被修改时,会替换掉目前的JasperLoader的实例,并通过再建立一个新的Jsp类加载器来实现JSP文件的HotSwap功能。

使用自定义类加载器解决JAR包多版本冲突问题3

症状:让sdk-1.0与sdk-2.0并存于项目,会导致如下状况:
tomcat与自定义类加载器_第3张图片
解决:自定义classloader,使得两个版本的jar包使用两个不同的classloader,这样就可以实现多个同类但不同版本的jar包并存:
tomcat与自定义类加载器_第4张图片

其它方案:1、微服务化,一个版本一个服务;2、shaded,参考本博----用shade打包来解决jar包冲突

附:

一些其他参考文章:
Java 类加载机制(阿里)-何时初始化类
知乎----如何实现Java类隔离加载?


  1. 头条:在tomcat中,为什么要使用自定义类加载器? ↩︎

  2. 深入理解 Tomcat(四)Tomcat 类加载器之为何违背双亲委派模型 ↩︎

  3. 基于sofaark轻松实现不同版本jar包类隔离机制 ↩︎

你可能感兴趣的:(java基础,jvm,tomcat,类加载器,classloader,双亲委派,包冲突,版本冲突,jar包冲突)