【Tomcat框架】Tomcat如何打破双亲委派机制?

Tomcat如何打破双亲委派机制?

Tomcat是一个Web框架,并且可以支持部署多个web项目,web项目在Tomcat被抽象的称为Context,即每一个web项目是一个Context。而每个Context是独立的,比如项目A可以引用spring1.0,而项目B可以引用spring2.0版本,如果是双亲委派机制,那么只能存在一个spring版本。Tomcat是如何打破双亲委派机制的呢?

什么是类加载?

Java 的类加载,就是把字节码格式“.class”文件加载到 JVM 的方法区,并在 JVM 的堆区建立一个java.lang.Class对象的实例,用来封装 Java 类相关的数据和方法。那 Class 对象又是什么呢?你可以把它理解成业务类的模板,JVM 根据这个模板来创建具体业务类对象实例。

JVM 并不是在启动时就把所有的“.class”文件都加载一遍,而是程序在运行过程中用到了这个类才去加载。JVM 类加载是由类加载器来完成的。

双亲委派机制

首先我们来复习一下双亲委派机制:

image-20210802131906207

  • BootstrapClassLoader 是启动类加载器,由 C 语言实现,用来加载 JVM 启动时所需要的核心类,比如rt.jarresources.jar等。
  • ExtClassLoader 是扩展类加载器,用来加载\jre\lib\ext目录下 JAR 包。
  • AppClassLoader 是系统类加载器,用来加载 classpath 下的类,应用程序默认用它来加载类。
  • 自定义类加载器,用来加载自定义路径下的类。

简单描述下:

每个类加载器负责一部分指定类的加载。若遇到某个类,需要加载,并不直接去加载,先让父加载器去查询是否加载过,若父类加载器加载过,则返回结束,否则让父类加载器尝试加载,若不是当前父类负责的加载内容,则向下返回给子类,让子类自己尝试加载。

这样的好处:

  1. 避免重复加载(class的唯一性)
  2. 防止破坏已有的一些系统的class

而Tomca t每个Context可能会存在相同全限定类名,比如项目A中有个类叫com.add.domain.User而项目B中也可能有个类叫com.add.domain.User。这样的情况肯定是要将两个类都加载,并且要实现项目之间的独立。或者是项目A和B都依赖了一个spring,但是版本是不同的,这样也需要都加载,并且要实现项目之间的独立。

JVM类加载源码分析

现在Java如果不搞个源码分析,都找不到工作了

首先要明确,上面双亲委派机制体系中,不是继承的关系,而是父子关系,是用一个指针指向父类加载器实现的,具体是实现ClassLoader类。我们来看看默认的双亲委派机制的类加载源码。

public abstract class ClassLoader {
   
 
    // 每个类加载器都有个父加载器
    private final ClassLoader parent;
    
    public Class<?> loadClass(String name) {
   
  
        // 查找一下这个类是不是已经加载过了
        Class<?> c = findLoadedClass(name);
        
        // 如果没有加载过
        if( c == null ){
   
          // 先委托给父加载器去加载,注意这是个递归调用
          if (parent != null) {
   
              c = parent.loadClass(name);
          }else {
   
              // 如果父加载器为空,查找 Bootstrap 加载器是不是加载过了
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值