【JVM】已验鼎真,鉴定为:妈妈加载的(双亲委派模型)

【JVM】已验鼎真,鉴定为:妈妈加载的(双亲委派模型)

在Java的世界中,类加载器(ClassLoader)是Java虚拟机(JVM)用来动态加载类的基础组件。双亲委派模型(Parent Delegation Model)是Java类加载机制中一个至关重要的设计,它确保Java类加载过程的安全性和稳定性。本文将简单介绍JVM中的类加载器机制及其双亲委派模型。

首先我们来看看类加载器。

一、类加载器概述

Java中的类加载器主要有以下几种:

  1. Bootstrap ClassLoader(引导类加载器)
    • 由C++实现,是JVM自身的一部分。
    • 负责加载Java的核心类库,例如rt.jar中的类。
  2. Extension ClassLoader(扩展类加载器)
    • sun.misc.Launcher$ExtClassLoader实现。
    • 负责加载Java扩展库(JDK扩展目录lib/ext中的JAR包)。
  3. 应用程序类加载器(Application Class Loader)
    • sun.misc.Launcher$AppClassLoader实现。
    • 负责加载应用程序的类路径(classpath)上的类。
  4. User-defined ClassLoader(用户自定义类加载器)
    • 通过继承java.lang.ClassLoader可以实现自定义类加载器。
    • 用于加载特定需求的类,例如网络类加载器、数据库类加载器等。

image-20240605215628999

二、双亲委派模型

双亲委派模型,准确来说,即当一个类加载器收到一个类的加载请求时,首先不会自己尝试去加载它,而是把这一请求委派给父类加载器去完成,这样层层委派,因此所有的加载请求都最终会被传送到顶层的启动类加载器中。

只有当父类加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载。

  1. 检查缓存:类加载器首先检查自己是否已经加载过该类,如果加载过则直接返回。
  2. 委派父类加载器:如果自己没有加载过,则将加载请求委派给父类加载器。
  3. 递归委派:父类加载器同样遵循上述步骤,递归检查其父类加载器,直到顶层的Bootstrap ClassLoader(启动类加载器)。
  4. 加载类:如果顶层的类加载器无法加载该类,则依次往下返回,由各级子类加载器尝试加载该类。
  5. 缓存加载结果:成功加载类后,将该类缓存以便下次直接使用。

双亲委派模型的优点

  1. 安全性:通过双亲委派机制,可以防止核心类库被篡改。例如,Java核心类库中的java.lang.String类只有由Bootstrap ClassLoader加载,防止应用程序自定义一个java.lang.String类来替换。
  2. 避免重复加载:确保同一个类只被加载一次。即使在不同的类加载器中,只要遵循双亲委派机制,类加载器会避免重复加载同一个类。
  3. 模块化:使得类加载器可以在一个隔离的环境中加载类,适应不同的需求,例如应用服务器中不同应用的隔离运行。

双亲委派模型的缺点

  1. 灵活性不足:在某些情况下,双亲委派模型的严格父子关系限制了类加载器的灵活性。例如,开发人员可能希望在应用程序中加载一个与系统类库版本不同的库。
  2. 调试困难:由于类加载过程涉及多个类加载器的协同工作,调试类加载问题时可能比较复杂,尤其是在遇到类加载冲突或类版本不一致的情况。

三、如何打破双亲委派模型

正常加载类的顺序,是用户自定义类加载器 -> 应用程序类加载器 -> 扩展类加载器 -> 引导类加载器,如果不遵循这个顺序,就是在打破双亲委派机制。

而双亲委派过程都是在loadClass方法中实现的,如果想要破坏这种机制,那么就自定义一个类加载器,重写其中的loadClass方法,使其不进行双亲委派即可。

例如:

public class CustomClassLoader extends ClassLoader {public CustomClassLoader(ClassLoader parent) {super(parent);}@Overridepublic Class<?> loadClass(String name) throws ClassNotFoundException {// 不委派给父类加载器,直接尝试加载目标类try {// 尝试从当前类加载器的资源路径加载类byte[] classData = loadClassData(name);if (classData != null) {return defineClass(name, classData, 0, classData.length);}} catch (Exception e) {// 忽略加载异常}// 如果当前类加载器无法加载,委派给父类加载器return super.loadClass(name);}private byte[] loadClassData(String name) {// 从文件或其他资源中读取类字节码的逻辑// ...return null; // 实际实现时应返回有效的字节码数据}
}

四、双亲委派模型的示例

以Tomcat为例,Apache Tomcat是一个广泛使用的Java Web服务器,一个web容器可能需要部署多个应用程序,不同的应用程序可能会依赖同一个第三方库的不同版本,但是不同版本的库中某一个类的全路径名可能是一样的。

它提供了一种机制来打破双亲委派模型,以支持不同Web应用之间的类隔离。Tomcat中,每个Web应用都有自己的类加载器,并且Tomcat的类加载机制允许在特定情况下打破双亲委派模型。

Tomcat的类加载器架构如下:

  1. Bootstrap ClassLoader:加载Java核心类库。
  2. System ClassLoader:加载Tomcat自身的类库。
  3. Common ClassLoader:加载Tomcat的共享类库。
  4. Webapp ClassLoader:每个Web应用有独立的类加载器,用于加载该应用的类和库。

如果采用默认的双亲委派类加载机制,无法加载多个相同的类。

所以,Tomcat破坏双亲委派原则,提供隔离的机制,为每个web容器单独提供一个WebAppClassLoader加载器,每个应用都有自己的类加载器WebAppClassLoader,该加载器重写了loadClass方法,会优先加载当前应用下的类,加载不到时再交给WebAppClassLoader的父加载器SharedClassLoader去加载。

打破双亲委派模型是一种特殊的需求,通常用于解决特定的类加载冲突或版本兼容问题。在Tomcat等应用服务器中,通过自定义类加载器和配置,可以实现对类加载过程的精细控制。理解和灵活应用类加载机制,可以帮助开发人员更好地管理和优化Java应用程序的运行环境。

结语

双亲委派机制属于类加载机制的后续,本来应该很早就发出来力,因为内容不多,但是因为笔者很懒所以拖到现在啦~属于是终于填坑了属于是。

参考文献

深入浅出Java类加载机制(双亲委派模型)与自定义类加载器实践_java类的装载机制-CSDN博客

java—双亲委派模型_java中双亲委派模型-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/23078.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安装和使用conda

Conda 是一个开源的软件包管理系统和环境管理系统&#xff0c;用于安装多个版本的软件包及其依赖关系&#xff0c;并在它们之间轻松切换。可以创建多个环境&#xff0c;并在环境中使用不同的python版本&#xff0c;并安装环境专属的python依赖包&#xff0c;可以用来避免python…

MySQL中:cmd下输入命令mysql -uroot -p 连接数据库错误

目录 问题cmd下输入命令mysql -uroot -p错误 待续、更新中 问题 cmd下输入命令mysql -uroot -p错误 解决 配置环境变量&#xff1a;高级系统设置——环境变量——系统变量——path编辑——新建——MySQL.exe文件路径&#xff08;如下图所示&#xff09; phpstudy2018软件下&am…

王学岗鸿蒙开发(北向)——————(二)TS基本语法详解

1&#xff0c;Ts(TypeScript)语法相当于JAVAScript类型&#xff0c;鸿蒙arkTs是基于TS语言的,当然artTs也融合了其它的语言。 2&#xff0c;本篇文章是基于n9版本。注意,有些语法是已经不能用的。 3&#xff0c; 4&#xff0c;变量:用来存储数据,数字字母组成&#xff0c;数字不…

泛微开发修炼之旅--07通过后端代码实现创建并发送待办、源码及示例

文章链接&#xff1a;泛微开发修炼之旅--07通过后端代码实现创建并发送待办、源码及示例

解决找不到api-ms-win-crt-runtime-l1-1-0.dll问题的5种方法

电脑已经成为我们生活和工作中不可或缺的工具&#xff0c;然而&#xff0c;由于各种原因&#xff0c;我们可能会遇到一些常见的问题&#xff0c;其中之一就是电脑缺失api-ms-win-crt-runtime-l1-1-0.dll文件。这个问题可能会导致电脑出现错误提示、程序无法正常运行等困扰。为了…

[Redis]Zset类型

Zset有序集合相对于字符串、列表、哈希、集合来说会有一些陌生。 它保留了集合不能有重复成员的特点&#xff0c;但与集合不同的是&#xff0c;有序集合中的每个元素都有一个唯一的浮点类型的分数&#xff08;score&#xff09;与之关联&#xff0c;着使得有序集合中的元素是可…

Python04:python代码设置作者/创建时间/文件名称

我们新建一个py文件时&#xff0c;如果希望文件开头有固定的内容&#xff0c;怎么设置呢&#xff1f; 比如代码作者、文件创建时间等。。。 1、点击左上角【Python】–>【Settings】设置 2、在弹出的新窗口找到【File and Code Templates】–>【Python Script】–>在右…

LeetCode70-爬楼梯

题目 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1 阶 1 阶2 阶 示例 2&#x…

6_5 test

Lucene 存储引擎 https://www.cnblogs.com/tech-lee/p/15225276.html\ 规范 问问题的技巧 提问者&#xff1a;要实现怎样的目标&#xff1f;自己计划是如何实现这个目标的&#xff1f;问题出现在哪个环节&#xff1f;自己为了解决这个问题&#xff0c;已经做了哪些尝试和工…

【ubuntu软件版本管理】利用update-alternatives管理ubuntu软件

​ 我们有的时候希望在安装了新软件之后保留旧版本的软件&#xff0c;比如希望保留旧版本的gcc&#xff0c;以防以前写的C编译出问题&#xff0c;这时候就需要版本管理软件update-alternatives。 ​ 在此之前我们需要先弄清楚&#xff0c;什么是ubuntu的软件&#xff1f;拿C源…

mysql中的笛卡尔积

在MySQL中,笛卡尔积(Cartesian Product)是指在进行多表连接时,如果没有指定连接条件,所有表中的每一行都会与其他表中的每一行进行组合,从而产生的结果集。笛卡尔积通常由交叉连接(CROSS JOIN)或者在缺少连接条件的普通连接产生。 生成笛卡尔积的示例 假设有两张表 t…

推荐系统学习 一

参考&#xff1a;一文看懂推荐系统&#xff1a;召回08&#xff1a;双塔模型——线上服务需要离线存物品向量、模型更新分为全量更新和增量更新_数据库全量更新和增量更新流程图-CSDN博客 一文看懂推荐系统&#xff1a;概要01&#xff1a;推荐系统的基本概念_王树森 小红书-CSD…

Python 全栈体系【四阶】(五十七)

第五章 深度学习 十三、自然语言处理&#xff08;NLP&#xff09; 2. 传统NLP处理技术 2.4 关键词提取 关键词提取是提取出代表文章重要内容的一组词&#xff0c;对文本聚类、分类、自动摘要起到重要作用。此外&#xff0c;关键词提取还能使人们便捷地浏览和获取信息。现实…

Centos7.9实现多台机器ssh免密登录

1.本机&#xff08;172.16.10.228&#xff09;先生成密钥对 ssh-keygen -t rsa 2.执行命令&#xff0c;把本机公钥拷贝到远程机器 ssh-copy-id rootdistinctIp 3.查看一下远程机器 、/root/.ssh/authorized_keys文件 cat /root/.ssh/authorized_keys 会看到里边多了个公钥…

Java 线程安全问题再深入

线程安全问题深入 线程安全问题 Java Singleton单例设计模式 单例设计模式的线程安全问题 所谓类的单例设计模式&#xff0c;就是采取一定的方法保证在整个的软件系统中&#xff0c;对某个类只能存在一个对象实例&#xff0c;并且该类只提供一个取得其对象实例的方法。 //使用懒…

LeetCode 1211, 55, 76

目录 1211. 查询结果的质量和占比题目链接表要求知识点思路代码&#xff08;有问题&#xff09;代码&#xff08;修正&#xff09; 55. 跳跃游戏题目链接标签思路代码 76. 最小覆盖子串题目链接标签思路代码 1211. 查询结果的质量和占比 题目链接 1211. 查询结果的质量和占比…

尼龙输送带的使用寿命是多久

尼龙输送带是一种常用的输送设备&#xff0c;用于物料输送和传送工作。它由尼龙帆布和橡胶等材料制成&#xff0c;具有高强度、耐磨损、耐高温、耐腐蚀等特点&#xff0c;因此在许多行业中得到广泛应用。 尼龙输送带的使用寿命主要受到以下因素的影响&#xff1a; 1.环境条件…

Kafka Streams介绍及在idea中的配置

Kafka Streams是一个用于构建实时流处理应用程序的客户端库。它基于Apache Kafka构建&#xff0c;提供了一种简单而强大的方式来处理和分析实时数据流。Kafka Streams为开发人员提供了丰富的功能和灵活性&#xff0c;使他们能够使用常用的编程语言&#xff08;如Java&#xff0…

Qt 的 d_ptr (d-pointer) 和 q_ptr (q-pointer)解析;Q_D和Q_Q指针

篇一&#xff1a; Qt之q指针&#xff08;Q_Q&#xff09;d指针&#xff08;Q_D&#xff09;源码剖析---源码面前了无秘密_qtq指针-CSDN博客 通常情况下&#xff0c;与一个类密切相关的数据会被作为数据成员直接定义在该类中。然而&#xff0c;在某些场合下&#xff0c;我们会…

这才是大模型价格战背后的真相

想必大家今天肯定被各家大模型厂商的降价新闻刷圈了&#xff0c;如果说 Meta Llama 3 的开源是国外大模型市场的搅局者&#xff0c;那 DeepSeek-V2 就是国内大模型市场的鲶鱼&#xff0c;但是价格战背后是大模型基础设施优化带来的物美价廉&#xff0c;还是浑水摸鱼的噱头&…