jvm双亲委派 vs 破坏双亲委派理解加载器的权责分配

 更新时间:2023年10月12日 11:45:38   作者:jacheut  
这篇文章主要为大家介绍了jvm双亲委派 vs 破坏双亲委派对比来理解加载器的权责分配,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

双亲委派模型

对于任意一个类,都需要由加载它的类加载器和这个类本身来一同确立其在Java虚拟机中的唯一性。

为什么需要双亲委派

如果不是同一个类加载器加载,即使是相同的class文件,也会出现判断不相同的情况,从而引发一些意想不到的情况,为了保证相同的class文件,在使用的时候,是相同的对象,jvm设计的时候,采用了双亲委派的方式来加载类。

双亲委派好处

  • 避免同一个类被多次加载;
  • 每个加载器只能加载自己范围内的类;

缺点:

顶层的启动类加载器的代码无法访问到底层的类加载器。

每一个类都有一个对应它的类加载器。系统中的 ClassLoder 在协同工作的时候会默认使用双亲委派模型 。即在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载。类加载的时候,首先会把该请求委派该父类加载器的 loadClass() 处理,因此所有的请求最终都应该传送到顶层的启动类加载器 BootstrapClassLoader中。当父类加载器无法处理时,才由自己来处理。特别当父类加载器为null时,会使用启动类加载器 BootstrapClassLoader 作为父类加载器。

父类加载器有自己的加载范围,范围内没有找到,则不加载,并返回给子类。

jvm提供了三种系统加载器:

  • 启动类加载器(Bootstrap ClassLoader):C++实现,在java里无法获取,负责加载/lib下的类。
  • 扩展类加载器(Extension ClassLoader): Java实现,可以在java里获取,负责加载/lib/ext下的类。
  • 系统类加载器/应用程序类加载器(Application ClassLoader):是与我们接触对多的类加载器,我们写的代码默认就是由它来加载,ClassLoader.getSystemClassLoader返回的就是它。

破坏双亲委派

为什么需要破坏双亲委派?

因为在某些情况下父类加载器需要委托子类加载器去加载class文件。受到加载范围的限制,父类加载器无法加载到需要的文件,以Driver接口为例,由于Driver接口定义在jdk当中的,而其实现由各个数据库的服务商来提供,比如mysql的就写了MySQL Connector,那么问题就来了,DriverManager(也由jdk提供)要加载各个实现了Driver接口的实现类,然后进行管理,但是DriverManager由启动类加载器加载,只能记载JAVA_HOME的lib下文件,而其实现是由服务商提供的,由系统类加载器加载,这个时候就需要启动类加载器来委托子类来加载Driver实现,从而破坏了双亲委派,这里仅仅是举了破坏双亲委派的其中一个情况。

破坏双亲委派的实现

我们结合Driver来看一下在spi(Service Provider Inteface)中如何实现破坏双亲委派。
先从DriverManager开始看,平时我们通过DriverManager来获取数据库的Connection:
在调用DriverManager的时候,会先初始化类,调用其中的静态块:

可以看到,load方法调用获取了当前线程中的上下文类加载器,那么上下文类加载器放的是什么加载器呢?

在sun.misc.Launcher中,我们找到了答案,在Launcher初始化的时候,会获取AppClassLoader,然后将其设置为上下文类加载器,而这个AppClassLoader,就是之前上文提到的系统类加载器Application ClassLoader,所以上下文类加载器默认情况下就是系统加载器。

以上就是浅谈jvm双亲委派和破坏双亲委派的详细内容,更多关于jvm双亲委派的资料请关注脚本之家其它相关文章!

相关文章

  • 浅谈java中为什么实体类需要实现序列化

    浅谈java中为什么实体类需要实现序列化

    下面小编就为大家带来一篇浅谈java中为什么实体类需要实现序列化。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • Java 不同版本的 Switch语句

    Java 不同版本的 Switch语句

    本文主要介绍了Java不同版本的Switch语句,自Java13以来,Switch表达式就被添加到Java核心库中,下面我们将介绍旧的Java Switch语句和新的Switch语句的区别,需要的朋友可以参考一下
    2022-06-06
  • Java中Swing类实例讲解

    Java中Swing类实例讲解

    这篇文章主要介绍了Java中Swing类实例讲解,文中用代码实例讲解的很清楚,有需要的同学可以研究下
    2021-02-02
  • 解决RedisTemplate的key默认序列化器的问题

    解决RedisTemplate的key默认序列化器的问题

    这篇文章主要介绍了解决RedisTemplate的key默认序列化器的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • Mybatis使用typeHandler加密的实现

    Mybatis使用typeHandler加密的实现

    本文详细介绍了如何在Mybatis中使用typeHandler对特定字段进行加密处理,涵盖了从引入依赖、配置Mybatis,到实现typeHandler继承类和配置mapper层的详细步骤,为需要在项目中实现字段加密的开发者提供了参考和借鉴
    2024-09-09
  • Java 实战项目锤炼之在线购书商城系统的实现流程

    Java 实战项目锤炼之在线购书商城系统的实现流程

    读万卷书不如行万里路,只学书上的理论是远远不够的,只有在实战中才能获得能力的提升,本篇文章手把手带你用java+jsp+mysql+servlet+ajax实现一个在线购书商城系统,大家可以在过程中查缺补漏,提升水平
    2021-11-11
  • 详解MyBatisPlus如何实现分页和查询操作

    详解MyBatisPlus如何实现分页和查询操作

    这篇文章主要为大家详细介绍了MyBatisPlus是如何实现分页和查询操作的,文中的示例代码讲解详细,对我们学习有一定的帮助,需要的可以参考一下
    2022-05-05
  • Spring Boot整合Redis的完整步骤

    Spring Boot整合Redis的完整步骤

    这篇文章主要给大家介绍了关于Spring Boot整合Redis的完整步骤,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • Java实现二分查找算法实例分析

    Java实现二分查找算法实例分析

    这篇文章主要介绍了Java实现二分查找算法,实例分析了二分查找算法的原理与相关实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • Spring MVC 处理一个请求的流程

    Spring MVC 处理一个请求的流程

    Spring MVC是Spring系列框架中使用频率最高的部分。不管是Spring Boot还是传统的Spring项目,只要是Web项目都会使用到Spring MVC部分。因此程序员一定要熟练掌握MVC部分。本篇博客简要分析Spring MVC处理一个请求的流程。
    2021-02-02

最新评论