点击上方“JavaEdge”,关注公众号

设为“星标”,好文章不错过!

说是双亲,其实多级单亲,无奈迎合历史的错误翻译吧。

1 工作流程

当一个类加载器收到一个类加载请求 在 JDK9 后,会首先搜索它的内建加载器定义的所有“具名模块”:

如果找到合适的模块定义,将会使用该加载器来加载

如果未找到,则会将该请求委派给父级加载器去加载

因此所有的类加载请求最终都应该被传入到启动类加载器(Bootstrap ClassLoader)中,只有当父级加载器反馈无法完成这个列的加载请求时(它的搜索范围内不存在这个类),子级加载器才尝试加载。

在类路径下找到的类将成为这些加载器的无名模块。

这里的父子关系是组合而不是继承。

双亲委派模型示意图

双亲委派模型的优点

避免重复加载 父类已经加载了,子类就不需要再次加载。eg,object 类。它存放在 rt.jar 中,无论哪个类加载器要加载这个类,最终都是委派给处于模型顶端的启动类加载器加载,因此 object 类在程序的各种加载环境中都是同一个类。

更安全 解决了各个类加载器的基础类的统一问题,如果不使用该种方式,那么用户可以随意定义类加载器来加载核心 API,会带来安全隐患。

双亲委派模型的实现

类加载的方式

通过命令行启动应用时由JVM初始化加载含有main()方法的主类。

通过Class.forName()方法动态加载,会默认执行初始化块(static{}),但是Class.forName(name,initialize,loader)中的initialze可指定是否要执行初始化块。

通过ClassLoader.loadClass()方法动态加载,不会执行初始化块。

自定义类加载器

实现方式

遵守双亲委派模型 继承ClassLoader,重写findClass()方法。

破坏双亲委派模型 继承ClassLoader,重写loadClass()方法。

通常我们推荐采用第一种方法自定义类加载器,最大程度上的遵守双亲委派模型。

如果有一个类加载器能加载某个类,称为定义类加载器,所有能成功返回该类的Class的类加载器都被称为初始类加载器。

自定义类加载的目的是想要手动控制类的加载,那除了通过自定义的类加载器来手动加载类这种方式,还有其他的方式么?

利用现成的类加载器进行加载

利用URLClassLoader进行加载

类加载实例

命令行下执行HelloWorld.java

该段代码大体经过了一下步骤:

寻找jre目录,寻找jvm.dll,并初始化JVM

产生一个Bootstrap ClassLoader

Bootstrap ClassLoader加载器会加载他指定路径下的java核心api,并且生成Extended ClassLoader加载器的实例,然后Extended ClassLoader会加载指定路径下的扩展java api,并将其父设置为Bootstrap ClassLoader

Bootstrap ClassLoader生成Application ClassLoader,并将其父Loader设置为Extended ClassLoader

最后由AppClass ClassLoader加载classpath目录下定义的类——HelloWorld类。

我们上面谈到 Extended ClassLoader和Application ClassLoader是通过Launcher来创建,现在我们再看看源代码

破坏双亲委派模型

双亲模型的问题

父加载器无法向下识别子加载器加载的资源。

JDBC

如下证明 JDBC 是启动类加载器加载,但 mysql 驱动是应用类加载器。而 JDBC 运行时又需要去访问子类加载器加载的驱动,就破坏了该模型。

JDK 自己为解决该问题,引入线程上下问类加载器,可以通过Thread的setContextClassLoader()进行设置

当为启动类加载器时,使用当前实际加载驱动类的类加载器

热替换

比如OSGI的模块化热部署,它的类加载器就不再是严格按照双亲委派模型,很多 可能就在平级的类加载器中执行了。

FAQ

ClassLoader通过一个类全限定名来获取二进制流,如果我们需通过自定义类加载其来加载一个Jar包的时候,难道要自己遍历jar中的类,然后依次通过ClassLoader进行加载吗?或者说我们怎么来加载一个jar包呢? 对于动态加载jar而言,JVM默认会使用第一次加载该jar中指定类的类加载器作为默认的ClassLoader。

假设我们现在存在名为sbbic的jar包,该包中存在ClassA和ClassB类(ClassA中没有引用ClassB)。现在我们通过自定义的ClassLoaderA来加载在ClassA这个类,此时ClassLoaderA就成为sbbic.jar中其他类的默认类加载器。即ClassB默认也会通过ClassLoaderA去加载。

如果一个类引用的其他的类,那么这个其他的类由谁来加载?

如果ClassA中引用了ClassB呢? 当类加载器在加载ClassA的时候,发现引用了ClassB,此时类加载如果检测到ClassB还没有被加载,则先回去加载。当ClassB加载完成后,继续回来加载ClassA。即类会通过自身对应的来加载其加载其他引用的类。

既然类可以由不同的加载器加载,那么如何确定两个类如何是同一个类?

JVM规定:对于任何一个类,都需要由加载它的类加载器和这个类本身一同确立在java虚拟机中的唯一性。即在jvm中判断两个类是否是同一个类取决于类加载和类本身,也就是同一个类加载器加载的同一份Class文件生成的Class对象才是相同的,类加载器不同,那么这两个类一定不相同。

目前交流群已有800+人,旨在促进技术交流,可关注公众号添加笔者微信邀请进群

喜欢文章,点个“在看、点赞、分享”素质三连支持一下~

java破坏双亲委派_JDK为何自己先破坏双亲委派模型?相关推荐

  1. 双亲委派机制_面试官:双亲委派机制的原理和作用是什么?

    说到双亲委派机制,就必须要先要弄清楚Java的类加载器 什么是类加载器 Java类加载器(ClassLoader)是Java运行时环境(JRE)的一部分,负责动态的将Java类加载到Java虚拟机的内 ...

  2. java写的股票技术分析_基于Java语言开发的个性化股票分析技术:量能突破模型(Energe-Break)...

    基于Java语言开发的个性化股票分析技术: 量能突破模型(Energe-Break) 一个用量能指标作为判定依据的条件分析模型,根据最近5天内是否有量能平台的突破以及涨跌幅的大小给每只股票评分评价,给 ...

  3. 此计算机未配置为允许委派用户凭据,Kerberos 协议转换和受限委派

    发布日期: 2004年12月02日 发布者 Frederick Chong,Microsoft Corporation 的软件设计工程师 本文档涉及包含在 Windows Server 2003 标准 ...

  4. 基于windows中委派的攻击思路(上)-约束性委派与非约束性委派

    文章目录 1. 前言 2. 发现具有委派关系的用户和计算机 2.1 原理 2.2 利用工具查找 1. ADFind 1.查询非约束委派的主机: 2.查询约束委派的主机 2. ldapsearch 1. ...

  5. java jdk 类加载机制_JDK源码阅读之类加载

    java类加载 类的生命周期(类加载过程) LLIUU+VPR 加载(Loading) 链接(Linking) 验证(Verification) 准备(Preparation) 解析(Resoluti ...

  6. java.time不存在_jdk安装成功,但是eclipse打开出现的错误,找不到java runtime

    笔记本上也安装了myeclipse,一开始是以为是不能同时安装两个,我的是64位操作系统.64位的jdk.64eclipse mars 在网上看了好几个方法,找到一个解决的方式http://www.c ...

  7. java图片不动了_JDK 12又来了,我学不动了...

    原标题:JDK 12又来了,我学不动了... 写在前面 看到 JDK 12又发布了,萌新不知不觉感觉瑟瑟发抖,从 Java 1.8的函数式编程思维和范式 到 Java 1.9的模块化特性的加持 以及还 ...

  8. java jdk的作用_jdk的作用是什么?jdk和jre区别介绍

    之前给大家介绍了jdk是什么意思,那么接下来要给大家讲到的就是jdk的作用以及jdk和jre之间的区别,一起来了解一下吧! 一.jdk的作用是什么? jdk是java的开发编译环bai境. 它里面包含 ...

  9. java jdk 检测安装_JDK如何安装和配置环境变量以及检验是否成功安装JDK的方法

    大家都知道JDK是JAVA运行的环境,JDK是将.java文件翻译成.class文件的虚拟机,只有经过编译后系统才能识别,不管是eclippse,还是Myeclipse,还是其他的JAVA编程的编译器 ...

最新文章

  1. api可以主动采集用户数据吗_数据埋点采集的那些事儿
  2. mariadb-10实现半同步复制及SSL安全复制
  3. Linux 下 svn 的使用
  4. 华为交换机 查看IP和MAC对应关系
  5. 231. 2的幂 golang
  6. sharding分表后主键_Sharding-JDBC 使用入门和基本配置
  7. SpringBoot 封装返回类以及session 添加获取
  8. RaiDrive通过WebDAV挂载阿里云盘
  9. 3月9日 英语笔记-英标
  10. Java毕设项目成都某4S店销售管理系统计算机(附源码+系统+数据库+LW)
  11. matlab hsi颜色,RGB 颜色空间转 HSI 颜色空间的matlab程序实现
  12. sas html5,什么是sas?
  13. 运维工作发展的几个阶段
  14. 「测试人的恶梦」测试用例设计之电梯、杯子、桌子、椅子、洗衣机
  15. 华为鸿蒙第一期公测,华为鸿蒙开启第二轮公测,新增7款机型,有你的吗?
  16. Spring框架——基于xml文件的相关配置
  17. Invalid data found when processing input
  18. 如何在Windows PC端将音乐同步到iPhone Xs的音乐库
  19. 载荷谱、雨流计数、ncode中雨流计数的实现
  20. 微点注册web服务器没反应,微点主动防御网络版客户端Web设置教程.doc

热门文章

  1. 汇编语言两位数的乘法
  2. day6 列表以及今日作业
  3. mac|小程序开发|taro|python|环境配置|罕见问题
  4. java 多线程编程(包括创建线程的三种方式、线程的生命周期、线程的调度策略、线程同步、线程通信、线程池、死锁等)
  5. 【微语】第五周(12.14~12.20)
  6. 地缘剧本杀 (十三):逃亡(原创小说连载,内含语音)
  7. [转]国内外常用钢号对照表
  8. 陕西师范大学计算机学院课表,陕西师范大学数学与信息科学学院课程表一.DOC...
  9. 关于HTML<table>标签如何合并单元格
  10. 9.28巨人网络笔试