双亲委派到底是个啥

简介: 双亲委派到底是个啥

很多人面试的时候或多或少都会遇到这个问题, Java双亲委派是啥?若是面试前没看面试宝典, 可能真的一时半会回答不上来。因为工作中压根就不会遇到或想这个问题。那我今天好好聊聊这个双亲委派机制。

其实看名思义,大概就能知道是个啥, 想想我们的祖传三辈的那个味。就是你的基因,是继承了上一辈的。 而你的父亲继承了你爷爷。 就一直往上找。 直至最顶层。 感觉像是金字塔,其实不然啊。扯远了,还是回到技术本身。

我们先想想,Java加载类的机制。是不是见过loadClass 这个方法。 里面的实现是啥。其实这个方法是在ClassLoader 类里面。

大概画个图,见图说话


图中我们大体就可以知道,双亲委派其实自己先不加载某个类,而是交由父类去加载,父类找不到了,才会自己去加载, 若是自己不可以加载,则会包类找不到的异常。

双亲委派的规定就是, 自己不先加载,而是交由父类去折腾加载,父类折腾加载不出来, 才会自己去折腾加载。这样做的目的是什么呢?

我觉的是这两点:

1、防止重复加载同一个class文件, 防重,不会出现一个模块下,都有一样的类。通过委托人去上面问问,看看是否有加载过了,就不用再加载一遍了,保证数据安全性。

2、保证某些核心的class文件不会篡改, 通过委托的方式, 对一些若是篡改的class文件,也不会去加载。不同的加载器加载同一个class,也不会是同一个class对象。保证了class执行安全。


那居然双亲委派有那么多好处,但我还是想打破它怎么办。

其实也挺简单, 就是自己去实现加载类的机制, loadClass 重写个loadClass方法,里面写自己的实现。那你知道有哪些是打破了双亲委派的。

这个我知道啊, tomcat的加载类就改了, 把双亲委派给打破了。

tomcat是怎么做的。tomcat webapp 下是放了我们不同的war ,但若是我们要部署两个war怎么办, 且两个war包的类有相同的。 若是通过双亲委派机制那样的做法是有问题, 会遇到加载的类不是想要的,冲突了。 tomcat为了做到让两个应用之间隔离,互不干扰, 就打破了双亲委派机制, 让自己加载自己的,不用去找什么父类的加载器去加载。


除了tomcat,其实我们先前写jdbc ,通过driver去加载不同厂商的数据库的驱动, 它是所谓的SPI 机制。这样他就不用通过统一的父类的加载器实现,而是通过自己的实现去加载,毕竟不同的厂商的实现驱动不一样的哈。若是交由父类加载器去实现的话,BootStrapClassLoader 会加载到不同厂商的驱动,这样是有问题的。显然是不可以的,Java代码中都没有调用它,你给我加载是啥意思,明显是坑我嘛!


DriverManager的解决方案是啥, 他是在初始化的时候, 搞了个上下文加载器。去获取Connection的时候,是使用 ‘线程上下文加载器’去加载Connection的,而这里的线程上下文加载器其实还是ApplicationClassLoader。

所以在获取Connection的时候,还是先找Extenstion ClassLoader和BootStrap ClassLoader, 只不过这两个加载器肯定是加载不到的,最终由Application ClassLoader 进行加载。其实这种情况, 有的人会认为 是破坏了双亲委派机制, 因为本来明明应该是由 BootStrap ClassLoader 进行加载的, 结果你来一手 “线程上下文加载器”,改掉了 ‘类加载器’。


有的人,觉得没有打破双亲委派机制, 只是改由, “线程上下文加载器”进行类加载了,但还是遵守了 :‘依次往上找父类加载器进行加载, 找不到时才由自身加载’。 认为“‘原则’”上是没有变的。


这都是 “智者见智仁者见仁”吧,各位看官自己判断掂量;。


扯了那么多。总结一下呗。


前置只是就是, JDK中默认的类加载器, 他有三个,分别是 AppClassLoader, Ext ClassLoader, BootStrap ClassLoader。AppClassLoader 的父加载器为 Ext ClassLoader , Ext ClassLoader 的父加载器为 BootStrap ClassLoader。这里的父子关系 并不是通过继承实现的。而是组合


什么是双亲委派机制: 加载器在加载过程中, 类交由父类加载器进行加载。父类加载器没有找到才由自身加载。


双亲委派机制目的:为了防止内存中存在多份同样的字节码(安全)

类加载规则:如果一个类由类加载器A加载,那么这个类的依赖类也是由「相同的类加载器」加载。

如何打破双亲委派机制:自定义ClassLoader,重写loadClass方法(只要不依次往上交给父加载器进行加载,就算是打破双亲委派机制)

打破双亲委派机制案例:Tomcat

  1. 为了Web应用程序类之间隔离,为每个应用程序创建WebAppClassLoader类加载器
  2. 为了Web应用程序类之间共享,把ShareClassLoader作为WebAppClassLoader的父类加载器,如果WebAppClassLoader加载器找不到,则尝试用ShareClassLoader进行加载
  3. 为了Tomcat本身与Web应用程序类隔离,用CatalinaClassLoader类加载器进行隔离,CatalinaClassLoader加载Tomcat本身的类
  4. 为了Tomcat与Web应用程序类共享,用CommonClassLoader作为CatalinaClassLoader和ShareClassLoader的父类加载器
  5. ShareClassLoader、CatalinaClassLoader、CommonClassLoader的目录可以在Tomcat的catalina.properties进行配置

线程上下文加载器:由于类加载的规则,很可能导致父加载器加载时依赖子加载器的类,导致无法加载成功(BootStrap ClassLoader无法加载第三方库的类),所以存在「线程上下文加载器」来进行加载。

目录
相关文章
|
Java 数据库连接
什么是双亲委派?如何打破双亲委派?
什么是双亲委派?如何打破双亲委派?
324 0
|
监控 druid Java
Spring Boot 3 集成 Druid 连接池详解
在现代的Java应用中,使用一个高效可靠的数据源是至关重要的。Druid连接池作为一款强大的数据库连接池,提供了丰富的监控和管理功能,成为很多Java项目的首选。本文将详细介绍如何在Spring Boot 3项目中配置数据源,集成Druid连接池,以实现更高效的数据库连接管理。
10620 2
Spring Boot 3 集成 Druid 连接池详解
|
负载均衡 安全 网络安全
载波相移CPS-SPWM调制方法的simulink建模与仿真
本课题研究载波相移CPS-SPWM调制方法的Simulink建模与仿真。CPS-SPWM通过在多个功率单元中引入载波相移,使开关动作错开,输出多电平PWM波形,接近理想正弦波。系统采用单极倍频调制波反相法,生成互补脉冲序列控制开关管通断。双极性CPS-PWM的电压电平数为n+1,基波分量是单个双极性PWM的N倍。仿真结果验证了该方法的有效性,核心程序基于MATLAB2022a实现。
|
监控 前端开发 安全
JVM工作原理与实战(十一):双亲委派机制
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了双亲委派机制、父类加载器、双亲委派机制的主要作用、双亲委派机制常见问题等内容。
1004 1
|
网络架构
深入了解会话描述协议(SDP)
【8月更文挑战第24天】
993 0
|
API 开发者
【Azure API 管理】API Management service (APIM) 如何实现禁止外网访问
【Azure API 管理】API Management service (APIM) 如何实现禁止外网访问
188 0
|
SQL 关系型数据库 MySQL
proxysql修改默认系统配置
proxysql修改默认系统配置
251 0
|
算法
详尽分享算法系列:日历算法
详尽分享算法系列:日历算法
498 0
|
存储 传感器 大数据
大数据定义详解
【4月更文挑战第9天】大数据,超常规工具处理的海量(TB-PB-EB)多样化数据,包含结构化与非结构化信息,生成速度快且真实性高。关键在于专业化处理以实现数据增值,依赖于计算机科学、统计学的理论与云计算的支撑。大数据分析提供决策支持,驱动业务创新和社会治理改善,与云计算紧密关联,共同塑造新兴领域。
848 4