当前位置:首页 > 科技  > 软件

秒懂双亲委派机制

来源: 责编: 时间:2024-06-24 17:19:16 252观看
导读前言最近知识星球中,有位小伙伴问了我一个问题:JDBC为什么会破坏双亲委派机制?这个问题挺有代表性的。双亲委派机制是Java中非常重要的类加载机制,它保证了类加载的完整性和安全性,避免了类的重复加载。这篇文章就跟大家一

前言

最近知识星球中,有位小伙伴问了我一个问题:JDBC为什么会破坏双亲委派机制?h7528资讯网——每日最新资讯28at.com

这个问题挺有代表性的。h7528资讯网——每日最新资讯28at.com

双亲委派机制是Java中非常重要的类加载机制,它保证了类加载的完整性和安全性,避免了类的重复加载。h7528资讯网——每日最新资讯28at.com

这篇文章就跟大家一起聊聊,Java中类加载的双亲委派机制到底是怎么回事,有哪些破坏双亲委派机制的案例,为什么要破坏双亲委派机制,希望对你会有所帮助。h7528资讯网——每日最新资讯28at.com

1 为什么要双亲委派机制?

我们的Java在运行之前,首先需要把Java代码转换成字节码,即class文件。h7528资讯网——每日最新资讯28at.com

然后JVM需要把字节码通过一定的方式加载到内存中的运行时数据区。h7528资讯网——每日最新资讯28at.com

这种方式就是类加载器(ClassLoader)。h7528资讯网——每日最新资讯28at.com

再通过加载、验证、准备、解析、初始化这几个步骤完成类加载过程,然后再由jvm执行引擎的解释器和JIT即时编译器去将字节码指令转换为本地机器指令进行执行。h7528资讯网——每日最新资讯28at.com

我们在使用类加载器加载类的时候,会面临下面几个问题:h7528资讯网——每日最新资讯28at.com

  • 如何保证类不会被重复加载?类重复加载会出现很多问题。
  • 类加载器是否允许用户自定义?
  • 如果允许用户自定义,如何保证类文件的安全性?
  • 如何保证加载的类的完整性?

为了解决上面的这一系列的问题,我们必须要引入某一套机制,这套机制就是:双亲委派机制。h7528资讯网——每日最新资讯28at.com

2 什么是双亲委派机制?

接下来,我们看看什么是双亲委派机制。h7528资讯网——每日最新资讯28at.com

双亲委派机制的基本思想是:当一个类加载器试图加载某个类时,它会先委托给其父类加载器,如果父类加载器无法加载,再由当前类加载器自己进行加载。h7528资讯网——每日最新资讯28at.com

这种层层委派的方式有助于保障类的唯一性,避免类的重复加载,并提高系统的安全性和稳定性。h7528资讯网——每日最新资讯28at.com

在Java中默认的类加载器有3层:h7528资讯网——每日最新资讯28at.com

  1. 启动类加载器(Bootstrap Class Loader):负责加载 %JAVA_HOME%/jre/lib 目录下的核心Java类库,比如:rt.jar、charsets.jar等。它是最顶层的类加载器,通常由C++编写。
  2. 扩展类加载器(Extension Class Loader):负责加载Java的扩展库,一般位于<JAVA_HOME>/lib/ext目录下。
  3. 应用程序类加载器(Application Class Loader):也称为系统类加载器,负责加载用户类路径(ClassPath)下的应用程序类。

用一张图梳理一下,双亲委派机制中的3种类加载器的层次关系:h7528资讯网——每日最新资讯28at.com

图片图片h7528资讯网——每日最新资讯28at.com

但这样不够灵活,用户没法控制,加载自己想要的一些类。h7528资讯网——每日最新资讯28at.com

于是,Java中引入了自定义类加载器。h7528资讯网——每日最新资讯28at.com

创建一个新的类并继承ClassLoader类,然后重写findClass方法。h7528资讯网——每日最新资讯28at.com

该方法主要是实现从那个路径读取 ar包或者.class文件,将读取到的文件用字节数组来存储,然后可以使用父类的defineClass来转换成字节码。h7528资讯网——每日最新资讯28at.com

如果想破坏双亲委派的话,就重写loadClass方法,否则不用重写。h7528资讯网——每日最新资讯28at.com

类加载器的层次关系改成:h7528资讯网——每日最新资讯28at.com

图片图片h7528资讯网——每日最新资讯28at.com

双亲委派机制流程图如下:h7528资讯网——每日最新资讯28at.com

图片图片h7528资讯网——每日最新资讯28at.com

具体流程大概是这样的:h7528资讯网——每日最新资讯28at.com

  • 需要加载某个类时,先检查自定义类加载器是否加载过,如果已经加载过,则直接返回。
  • 如果自定义类加载器没有加载过,则检查应用程序类加载器是否加载过,如果已经加载过,则直接返回。
  • 如果应用程序类加载器没有加载过,则检查扩展类加载器是否加载过,如果已经加载过,则直接返回。
  • 如果扩展类加载器没有加载过,则检查启动类加载器是否加载过,如果已经加载过,则直接返回。
  • 如果启动类加载器没有加载过,则判断当前类加载器能否加载这个类,如果能加载,则加载该类,然后返回。
  • 如果启动类加载器不能加载该类,则交给扩展类加载器。扩展类加载器判断能否加载这个类,如果能加载,则加载该类,然后返回。
  • 如果扩展类加载器不能加载该类,则交给应用程序类加载器。应用程序类加载器判断能否加载这个类,如果能加载,则加载该类,然后返回。
  • 如果应用程序类加载器不能加载该类,则交给自定义类加载器。自定义类加载器判断能否加载这个类,如果能加载,则加载该类,然后返回。
  • 如果自定义类加载器,也无法加载这个类,则直接抛ClassNotFoundException异常。

这样做的好处是:h7528资讯网——每日最新资讯28at.com

  • 保证类不会重复加载。加载类的过程中,会向上问一下是否加载过,如果已经加载了,则不会再加载,这样可以保证一个类只会被加载一次。
  • 保证类的安全性。核心的类已经被启动类加载器加载了,后面即使有人篡改了该类,也不会再加载了,防止了一些有危害的代码的植入。

3 破坏双亲委派机制的场景

既然Java中引入了双亲委派机制,为什么要破坏它呢?h7528资讯网——每日最新资讯28at.com

答:因为它有一些缺点。h7528资讯网——每日最新资讯28at.com

下面给大家列举一下,破坏双亲委派机制最常见的场景。h7528资讯网——每日最新资讯28at.com

3.1 JNDI

JNDI是Java中的标准服务,它的代码由启动类加载器去加载。h7528资讯网——每日最新资讯28at.com

但JNDI要对资源进行集中管理和查找,它需要调用由独立厂商在应用程序的ClassPath下的实现了JNDI接口的代码,但启动类加载器不可能“认识”这些外部代码。h7528资讯网——每日最新资讯28at.com

为了解决这个问题,Java后来引入了线程上下文类加载器(Thread Context ClassLoader)。h7528资讯网——每日最新资讯28at.com

这个类加载器可以通过java.lang.Thread类的setContextClassLoader()方法进行设置。h7528资讯网——每日最新资讯28at.com

如果创建线程时没有设置,他将会从父线程中继承一个,如果在应用程序的全局范围内都没有设置过的话,那这个类加载器默认就是应用程序类加载器。h7528资讯网——每日最新资讯28at.com

有了线程上下文加载器,JNDI服务就可以使用它去加载所需要的SPI代码,也就是父类加载器请求子类加载器去完成类加载的动作,这样就打破了双亲委派机制。h7528资讯网——每日最新资讯28at.com

3.2 JDBC

原生的JDBC中Driver驱动本身只是一个接口,并没有具体的实现,具体的实现是由不同数据库类型去实现的。h7528资讯网——每日最新资讯28at.com

例如,MySQL的mysql-connector.jar中的Driver类具体实现的。h7528资讯网——每日最新资讯28at.com

原生的JDBC中的类是放在rt.jar包,是由启动类加载器进行类加载的。h7528资讯网——每日最新资讯28at.com

在JDBC中需要动态去加载不同数据库类型的Driver实现类,而mysql-connector.jar中的Driver实现类是用户自己写的代码,启动类加载器肯定是不能加载的,那就需要由应用程序启动类去进行类加载。h7528资讯网——每日最新资讯28at.com

为了解决这个问题,也可以使用线程上下文类加载器(Thread Context ClassLoader)。h7528资讯网——每日最新资讯28at.com

3.3  Tomcat容器

Tomcat是Servlet容器,它负责加载Servlet相关的jar包。h7528资讯网——每日最新资讯28at.com

此外,Tomcat本身也是Java程序,也需要加载自身的类和一些依赖jar包。h7528资讯网——每日最新资讯28at.com

这样就会带来下面的问题:h7528资讯网——每日最新资讯28at.com

  1. 一个Tomcat容器下面,可以部署多个基于Servlet的Web应用,但如果这些Web应用下有同名的Servlet类,又不能产生冲突,需要相互独立加载和运行才行。
  2. 但如果多个Web应用,使用了相同的依赖,比如:SpringBoot、Mybatis等。这些依赖包所涉及的文件非常多,如果全部都独立,可能会导致JVM内存不足。也就是说,有些公共的依赖包,最好能够只加载一次。
  3. 我们还需要将Tomcat本身的类,跟Web应用的类隔离开。

这些原因导致,Tomcat没有办法使用传统的双亲委派机制加载类了。h7528资讯网——每日最新资讯28at.com

那么,Tomcat加载类的机制是怎么样的?h7528资讯网——每日最新资讯28at.com

图片图片h7528资讯网——每日最新资讯28at.com

  • CommonClassLoader:是Tomcat最基本的类加载器,它加载的类可以被Tomcat容器和Web应用访问。
  • CatalinaClassLoader:是Tomcat容器私有的类加载器,加载类对于Web应用不可见。
  • SharedClassLoader:各个Web应用共享的类加载器,加载的类对于所有Web应用可见,但是对于Tomcat容器不可见。
  • WebAppClassLoader:各个Web应用私有的类加载器,加载类只对当前Web应用可见。比如不同war包应用引入了不同的Spring版本,这样能加载各自的Spring版本,相互隔离。

h7528资讯网——每日最新资讯28at.com

3.4 热部署

由于用户对程序动态性的追求,比如:代码热部署、代码热替换等功能,引入了OSGi(Open Service Gateway Initiative)。h7528资讯网——每日最新资讯28at.com

OSGi中的每一个模块(称为Bundle)。h7528资讯网——每日最新资讯28at.com

当程序升级或者更新时,可以只停用、重新安装然后启动程序的其中一部分,对企业来说这是一个非常诱人的功能。h7528资讯网——每日最新资讯28at.com

OSGi的Bundle类加载器之间只有规则,没有固定的委派关系。h7528资讯网——每日最新资讯28at.com

各个Bundle加载器是平级关系。h7528资讯网——每日最新资讯28at.com

不是双亲委派关系。h7528资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-96058-0.html秒懂双亲委派机制

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 深入解析复杂SQL查询及其在C#中的应用

下一篇: 有没有并发编程经验,一问这个类便知!

标签:
  • 热门焦点
  • 8月总票房已突破10亿!《封神》第一:口碑已经成了

    8月5日消息,据灯塔专业版数据,截至8月5日9时35分,8月总票房(含预售)已突破10亿。其中,《封神》以大比分的优势领先。根据官方消息,目前该片总票房已经超过14.
  • 微信语音大揭秘:为什么禁止转发?

    大家好,我是你们的小米。今天,我要和大家聊一个有趣的话题:为什么微信语音不可以转发?这是一个我们经常在日常使用中遇到的问题,也是一个让很多人好奇的问题。让我们一起来揭开这
  • 一篇文章带你了解 CSS 属性选择器

    属性选择器对带有指定属性的 HTML 元素设置样式。可以为拥有指定属性的 HTML 元素设置样式,而不仅限于 class 和 id 属性。一、了解属性选择器CSS属性选择器提供了一种简单而
  • 虚拟键盘 API 的妙用

    你是否在遇到过这样的问题:移动设备上有一个固定元素,当激活虚拟键盘时,该元素被隐藏在了键盘下方?多年来,这一直是 Web 上的默认行为,在本文中,我们将探讨这个问题、为什么会发生
  • 微软邀请 Microsoft 365 商业用户,测试视频编辑器 Clipchamp

    8 月 1 日消息,微软近日宣布即将面向 Microsoft 365 商业用户,开放 Clipchamp 应用,邀请用户通过该应用来编辑视频。微软于 2021 年收购 Clipchamp,随后开始逐步整合到 Microsof
  • 大厂卷向扁平化

    来源:新熵作者丨南枝 编辑丨月见大厂职级不香了。俗话说,兵无常势,水无常形,互联网企业调整职级体系并不稀奇。7月13日,淘宝天猫集团启动了近年来最大的人力制度改革,目前已形成一
  • 阿里大调整

    来源:产品刘有媒体报道称,近期淘宝天猫集团启动了近年来最大的人力制度改革,涉及员工绩效、层级体系等多个核心事项,目前已形成一个初步的&ldquo;征求意见版&rdquo;:1、取消P序列
  • 苹果公司要求三星和LG Display生产「无边框」OLED iPhone显示屏

    据 The Elec 报道,苹果已要求其供应商为未来的 iPhone 型号开发「无边框」OLED 显示面板。苹果显然已要求三星和 LG Display 开发新的 OLED 显示面
  • 联想YOGA 16s 2022笔记本将要推出,屏幕支持触控功能

    联想此前宣布,将于11月2日19:30召开联想秋季轻薄新品发布会,推出联想 YOGA 16s 2022 笔记本等新品。官方称,YOGA 16s 2022 笔记本将搭载 16 英寸屏幕,并且是一
Top