双亲委派模型

双亲委派模型并不是一种强制性的约束,只是JDK官方推荐的一种方式。

每⼀个类都有⼀个对应它的类加载器。系统中的 ClassLoder 在协同⼯作的时候会默认使⽤ 双亲委派模型 。

JVM启动的时候,并不会一次性加载所有的类,而是根据需要去动态加载。也就是说,大部分类在具体用到的时候才会去加载,这样对内存更加友好。且在类加载的时候,系统会⾸先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载。

加载的时候,他不会先去尝试自己去加载这个类,而是会把该请求委派该⽗类加载器的 loadClass() 去处理,因此所有的请求最终都应该传送到顶层的启动类加载器 BootstrapClassLoader 中。当⽗类加载器⽆法处理时(在它的加载路径下没有找到所需加载的 Class),才由⾃⼰来处理(调用自己的findclass()方法来加载类)。当⽗类加载器为null时,会使⽤启动类加载器BootstrapClassLoader 作为⽗类加载器。

7.1. 优点

1.保证JDK的核心类会被优先加载

2.保证java程序的稳定运行,可以避免类的重复加载,也保证了Java的核心API不会被篡改

3.不论是哪个类加载器去加载某个类,最终都是委托给顶层的启动类加载器去进行加载,这样就保证了使用不同的类加载器去加载最终获得的都是同一个Object对象

7.2. 破坏双亲委派机制:

自定义加载器的话,需要继承classLoader。如果我们不想打破双亲委派模型,就重写ClassLoader 类中的findclass()方法即可,无法被父类加载器加载的类最终会通过这个方法被加载。但是,如果想打破双亲委派模型则需要重写loadclass()方法。

7.2.1. 为什么是重写 loadclass()方法打破双亲委派模型呢?

双亲委派模型的执行流程已经解释了:

类加载器在进行类加载的时候,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成(调用父加载器 loadclass()方法来加载类)。

7.2.2. 方法:

  • 可以⾃⼰定义⼀个类加载器,重写loadClass方法;
  • Tomcat 可以加载自己目录下的 class 文件,并不会传递给父类的加载器;(阿里文章)
  • Java 的 SPI,发起者 BootstrapClassLoader 已经是最上层了,它直接获取了 AppClassLoader 进行驱动加载,和双亲委派是相反的。

7.3. JVM 判定两个Java 类是否相同的具体规则:

JVM不仅要看类的全名是否相同,还要看加载此类的类加载器是否一样。只有两者都相同的情况,才认为两个类是相同的。即使两个类来源于同一个class文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那这两个类就必定不相同。

7.4. 流程

  1. loadClass(): 这是类加载机制的入口点,当需要加载一个类时,这个方法会被调用。它遵循双亲委派模型,首先检查该类是否已经被当前类加载器加载过(通过查询其内部缓存)。如果没有加载过,loadClass()不会直接去查找类,而是先委托给其父类加载器去尝试加载。
  2. 双亲委派模型: 在loadClass()方法内部,如果父类加载器存在(非Bootstrap ClassLoader,因为它没有父加载器),则递归地调用父加载器的loadClass()方法。这一过程会一直向上委托,直到到达 Bootstrap ClassLoader。如果父加载器无法加载这个类(返回null),那么控制权会逐级返回到原始请求加载的类加载器。
  3. findClass(): 当委派链中的所有类加载器都无法加载这个类时,最终控制流会回到最初请求加载的类加载器,并调用其findClass()方法。这是自定义加载逻辑实现的地方,可以通过覆盖这个方法来从特定来源(如文件系统、数据库、网络等)加载类的二进制数据,并使用defineClass()方法将这些二进制数据转换为JVM可识别的Class对象。
  4. defineClass(): findClass()内部通常会使用defineClass()方法来完成类的定义工作,即将字节码转化为Class对象并加载到Java虚拟机中。此方法可以看作是将二进制数据“定义”为一个Java类型的点,它也是类加载过程中真正创建类的实例的地方。
  • 19
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值