糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > 为什么使用双亲委派机制以及如何破坏双亲委派

为什么使用双亲委派机制以及如何破坏双亲委派

时间:2023-03-22 17:12:35

相关推荐

为什么使用双亲委派机制以及如何破坏双亲委派

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

当某个特定的类加载器它在接到需要加载类的请求时,这个类会首先查看自己已加载完的类中是否包含这个类,如果有就返回,没有的话就会把加载的任务交给父类加载器加载,以此递归,父类加载器如果可以完成类加载任务,就返回它,当父类加载器无法完成这个加载任务时,才会不得已自己去加载。这种机制就叫做双亲委派机制。

工作机制

类装载器就是寻找类的字节码文件,并构造出类在JVM内部表示的对象组件。在Java中,类装载器把一个类装入JVM中,要经过以下步骤:

1) 装载:查找和导入Class文件;

2) 链接:把类的二进制数据合并到JRE中;

(a)校验:检查载入Class文件数据的正确性;

(b)准备:给类的静态变量分配存储空间;

(c)解析:将符号引用转成直接引用;

3) 初始化:对类的静态变量,静态代码块执行初始化操作

类加载器与双亲委派模型

类加载器

1) Bootstrap ClassLoader :

将存放于lib目录中的,或者被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别的(仅按照文件名识别,如 rt.jar

名字不符合的类库即使放在lib目录中也不会被加载)类库加载到虚拟机内存中。启动类加载器无法被Java程序直接引用

2) Extension ClassLoader :

将libext目录下的,或者被java.ext.dirs系统变量所指定的路径中的所有类库加载。开发者可以直接使用扩展类加载器。

3) Application ClassLoader : 负责加载用户类路径(ClassPath)上所指定的类库,开发者可直接使用。

双亲委派模型

工作过程:类加载器接收类加载的请求,先把请求委托给父类加载器去完成,所有层次的类加载器都是如此,因此所有的加载请求都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载。

反射

Reflection机制允许程序在正在执行的过程中,利用Reflection APIs获取任何已知名称的类的内部信息,并能够在执行过程中,动态生成instances、变更fields内容或唤起methods。

二、为什么要使用双亲委派机制?

首先明确一点:jvm如何认定两个对象同属于一个类型,必须同时满足下面两个条件: 都是用同名的类完成实例化的。两个实例各自对应的同名的类的加载器必须是同一个。比如两个相同名字的类,一个是用系统加载器加载的,一个扩展类加载器加载的,两个类生成的对象将被jvm认定为不同类型的对象。

java虚拟机只会在不同的类的类名相同且加载该类的加载器均相同的情况下才会判定这是一个类。如果没有双亲委派机制,同一个类可能就会被多个类加载器加载,如此类就可能会被识别为两个不同的类,相互赋值时问题就会出现。

双亲委派机制能够保证多加载器加载某个类时,最终都是由一个加载器加载,确保最终加载结果相同。

没有双亲委派模型,让所有类加载器自行加载的话,假如用户自己编写了一个称为java.lang.Object的类,并放在程序的ClassPath中,系统就会出现多个不同的Object类,

Java类型体系中基础行为就无法保证,应用程序就会变得一片混乱。

三,能不能自己写个类叫java.lang.System?

答案:通常不可以,但可以采取另类方法达到这个需求。

解释:为了不让我们写System类,类加载采用委托机制,这样可以保证爸爸们优先,爸爸们能找到的类,儿子就没有机会加载。而System类是Bootstrap加载器加载的,就算自己重写,也总是使用Java系统提供的System,自己写的System类根本没有机会得到加载。

但是,我们可以自己定义一个类加载器来达到这个目的,为了避免双亲委托机制,这个类加载器也必须是特殊的。由于系统自带的三个类加载器都加载特定目录下的类,如果我们自己的类加载器加载一个特殊的目录,那么系统的加载器就无法加载,也就是最终还是由我们自己的加载器加载

四、破坏双亲委派

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

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

4.2,如何破坏双亲委派机制原则

双亲委派机制原则在loadclass方法中。

只需要绕开loadclass方法中即可。

1.自定义类加载器 ,重写loadclass方法

2, SPI机制绕开loadclass 方法。当前线程设定关联类加载器。

SPI原理:类加载器如何打破双亲委派加载机制(SPI原理) - SegmentFault 思否

如果觉得《为什么使用双亲委派机制以及如何破坏双亲委派》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。