双亲委派机制讲解

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

研究类加载的过程需要了解双亲委派机制。但是,只知道双亲委派机制并不足够,我们的目的是要了解为什么要使用双亲委派机制,以及它的原理是什么。我们必须了解双亲委派机制的逻辑思想,然后思考这个思想是否可以被借鉴,用于我们自己的工作中。这才是学习知识的目的。
例如,双亲委派机制避免了类的重复加载,也避免了核心类库的被篡改。因此,在设计框架底层时,底层的东西应该是不容易被篡改或者攻击的。我们可以借鉴双亲委派机制来实现这个目标。
另外,双亲委派机制的实现使用了责任链设计模式。通过研究责任链设计模式,我们可以理解委派的原理。我们还可以思考,哪些场景适合使用责任链设计模式。多思考,才是学习的真谛。只有将学到的东西应用于工作中,才能真正提升自己的能力。

一、什么是双亲委派机制?

双亲委派机制是当类加载器需要加载某一个.class字节码文件时,则首先会把这个任务委托给他的上级类加载器,递归这个操作,如果上级没有加载该.class文件,自己才会去加载这个.class。
 通过观察会发现,引导类加载器,确实只加载了java home下的/jre/lib目录下的类,扩展类加载器加载了java扩展目录里面的类。但是, 应用程序类加载器, 加载的类包含了java home下/jre/lib目录, java home扩展目录下的类, 还有responsitory仓库下的类, 还有idea的类, 还有就是我们的类路径下target的类。问题来了, 为什么AppClassLoader加载器加载了引导类加载器和扩展类加载器要加载的类呢? 这样加载不是重复了么?其实, 不会重复加载, appClassLoader主要加载的类就是target目录下的类, 其他目录下的类事实上基本不会加载. 为什么呢? 这是因为双亲委派机制。
在这里插入图片描述
上面这个图就是双亲委派机制的图. 这也是类加载的原理。一共分为两部分:

一部分是查找
另一部分是加载
就以自定义的java.lxl.jvm.Math类为例,我们来看看这个类是如何被类加载器加载的。

第一步: 首先是由应用程序类加载器去查找java.lxl.jvm.Math类, 他要去看他已经加载的类中是否有这个类, 如果有, 就直接返回, 如果没有, 就去加载这个类,但是不是由应用程序类加载器直接加载。而是委托他的父类也就是扩展类加载器去加载。

第二步:扩展类加载器也是先搜索,查看已经加载的类是否有java.lxl.jvm.Math, 如果有就返回,如果没有就加载这个类。在加载的时候,也不是由自己来加载,而是委托他的父类,引导类加载器去加载。

第三步:引导类加载器先查找已经加载的类中是否有这个类,有则返回,没有就去加载这个类。这时候, 我们都知道, Math类是我自己定义的, 引导类加载器中不可能有, 加载失败,所以, 他就会去加载这个类。回去扫描/lib/jar包中有没有这个类,发现没有,于是让扩展类加载器去加载, 扩展类加载器会去扫描扩展包lib/jar/ext包,里面有没有呢? 当然也没有, 于是委托应用程序类加载器, ok, 应用程序类加载器是有的, 于是就可以加载了, 然后返回这个类。

【通过分析,我们可以得出,双亲委派机制的实现使用的是责任链设计模式。】

那么, 这里有一个问题, 那就是, 由应用程序类加载器首先加载, 然后最后又回到了应用程序类加载器. 绕了一圈又回来了, 这样是不是有些多此一举呢, 循环了两次? 为什么一定要从应用程序类加载器加载呢? 直接从引导类加载器加载不好么?只循环一次啊…

其实, 对于我们的项目来说, 95%的类都是我们自己写的, 因此, 而我们自己写的类是有应用程序类加载器加载. 其实,应用程序类加载器只有在第一次的时候, 才会加载两次. 以后, 当再次使用到这个类的时候, 直接去问应用程序类加载器, 有这个类么? 已经有了, 就直接返回了.

二、为什么叫双亲委派机制

双:代表是两两的意思。亲:代表两者之间有着千丝万缕的关系。委派:则是我们个人办不到的事情,委托别人去帮我们完成。总体来说,就是当子类加载器无法完成这件事时,则会委托父加载器去完成,当父加载器说这不是我做的事情时,则该任务又会落回到子类加载器,此时,子类加载器只能自己去完成该事情。通过上面的阐述,我们则可以明白为什么叫双亲委派机制了,两两之间相互委托对方。(以上纯属个人理解,如有错误之处,请指出)

三、双亲委派的作用

①防止加载同一个.class。通过委托去询问上级是否已经加载过该.class,如果加载过了,则不需要重新加载。保证了数据安全。
  ②保证核心.class不被篡改。通过委托的方式,保证核心.class不被篡改,即使被篡改也不会被加载,即使被加载也不会是同一个class对象,因为不同的加载器加载同一个.class也不是同一个Class对象。这样则保证了Class的执行安全。

请添加图片描述
请添加图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java码库

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值