类加载机制之双亲委派模型、作用、源码、SPI打破双亲委派模型

双亲委派模型

        • 双亲委派工作机制
        • 双亲委派的作用
        • 双亲委派的实现源码
        • SPI打破双亲委派

应用程序是由三种类加载器相互配合,从而实现类加载,除此之外还可以加入自己定义的类的加载器。

类加载器之间的层次关系,称为双亲委派模型(Parents Delegation Model)。该模型要求除了顶层的启动类加载器外,其他的类加载器都要有自己的父类加载器。这里的父类关系一般通过组合关系(Composition)来实现,而不是继承关系(Inheritance)。

在这里插入图片描述

双亲委派工作机制

一个类加载器首先将类加载请求转发到父类加载器,只有当父类加载器无法完成时菜尝试自己加载。

双亲委派的作用
  1. 每个类只会加载一次,解决了各个类加载器加载基础类的统一问题(基础类库由上层的加载器进行加载)
  2. 防止恶意破坏的类加载,内存中不会出现多份同样的字节码的系统类iii,保证Java程序安全稳定运行。

例如:java.lang .object存放在rt.jar中,如果编写另外—个java.lang.Object并放到ClassPath 中,程序可以编译通过。由于双亲委派模型的存在,所以在rt.jar中的Object比在ClassPath 中的 Object 优先级更高,因为rt.jar中的object使用的是启动类加载器,而ClassPath中的 object使用的是应用程序类加载器。rt.jar中的Object优先级更高,那么程序中使用的所有的 Object都是由启动类加载器所加载的Object 。

双亲委派的实现源码

以下是抽象类 java.lang.ClassLoader的代码片段,其中的loadClass()方法运行过程如下:先检查类是否已经加载过,如果没有则让父类加载器去加载。当父类加载器加载失败时抛出 ClassNotFoundException,此时尝试自己去加载。

public abstract class ClassLoader{
    //The parent class loader for delegation
    private final ClassLoader parent;
    
    public Class<?> loadClass(String name) throws ClassNotFoundException{
        return loadClass(name,false);
    }
    
    protected Class<?> loadClass(String name,boolean resolve) throws ClassNotFoundException{
        synchronized (getClassLoadingLock(name)){
            //First,check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if(c == null){
                try{
                    if (parent != null){
                        c = parent.loadClass(name,false);
                    }else{
                        c = findBootstrapClassOrNull(name);
                    }
                }catch (ClassNotFoundException e){
                     //ClassNotFoundException thrown if class not foundl from the non-null parent class loader
                }
                
                if (c == null){
                    // If still not found,then invoke findclass in orderll to find the class.
					c = findClass(name);
                }
            }
            if(resolve){
                resolveClass(c);
            }
            return c;
        }
    }
    protected Class<?> findClass(String name) throws ClassNotFoundException{
        throw new ClassNotFoundException(name);
    }
}
SPI打破双亲委派

SPI(Service Provider Interface),是一种服务发现机制,它通过在ClassPath路径下的META-INF/ services文件夹查找文件,自动加载文件里所定义的类。
如下图,SPI核心类定义在rt.jar中(例如:java.lang.Driver接口),所以java.lang.Driver接口本身是由启动类加载器加载,当调用java.lang.Driver接口的实现类时,启动类加载器是无法加载实现类的,这个时候就提供了线程上下文类加载器(Thread context ClassLoader )加载实现类,ThreadcontextClassLoader是可以通过 java.lang.Thread #setcontextclassLoader方法设置类加载器,这样就打破了双亲委派的类加载模式。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

印象笔记04: 如何将印象笔记超级会员价值最大化利用?

印象笔记04&#xff1a; 如何将印象笔记超级会员价值最大化利用&#xff1f; 为什么有这个问题 我不知道有没有人一开始接触印象笔记觉得非常好。奈何只能两个设备同步&#xff0c;局限太多。而会员活动比较优惠——就开了会员。而且我开了十年……。只能开发一下看看怎么最大…

C#用StringBuilder高效处理字符串

目录 一、背景 二、使用StringBuilder便捷、高效地操作字符串 三、实例 1.源码 2.生成效果 四、实例中知识点 1.StringBuilder类 一、背景 符串是不可改变的对象&#xff0c;字符串在创建以后&#xff0c;就不会被改变&#xff0c;当使用字符串对象的Replace、split或Re…

Flappy Bird QDN PyTorch博客 - 代码解读

Flappy Bird QDN PyTorch博客 - 代码解读 介绍环境配置项目目录结构QDN算法重要函数解读preprocess(observation)DeepNetWork(nn.Module)BirdDQN类主程序部分 介绍 在本博客中&#xff0c;我们将介绍如何使用QDN&#xff08;Quantile Dueling Network&#xff09;算法&#xf…

RK3399平台入门到精通系列讲解(实验篇)信号驱动 IO 实验

🚀返回总目录 文章目录 一、什么是信号驱动IO1.1、信号驱动IO1.2、fcntl 函数介绍二、信号驱动 IO 实验源码2.1、Makefile2.2、驱动部分代码2.3、测试应用代码一、什么是信号驱动IO 1.1、信号驱动IO 信号驱动 IO 不需要应用程序查询设备的状态,一旦设备准备就绪,会触发 SI…

ASP.NETCore WebAPI 入门 杨中科

ASP.NETCore WebAPI入门1 回顾 mvc开发模式 前端代码和后端代码是混在一个项目之中 WEB API 1、什么是结构化的Http接口。Json。 2、Web API项目的搭建。 3、Web API项目没有Views文件夹。 4、运行项目&#xff0c;解读代码结构。 5、【启用OpenAPI支持】→>swagger,在界…

视频文字想要提取应该使用哪些软件呢

随着短视频的兴起&#xff0c;快手成为了很多人喜爱的平台。有时候&#xff0c;我们看到一些有趣的视频&#xff0c;想要提取其中的文字内容&#xff0c;却不知道该如何操作。今天&#xff0c;我们就来介绍一种使用水印云快手提取视频文字的方法。 首先&#xff0c;我们需要下…

Java Review - Spring BeanUtils 踩坑记

文章目录 概述Spring BeanUtils基本使用Code忽略了属性类型导致拷贝失败同一字段在不同的类中定义的类型不一致同一个字段分别使用包装类和基本类型且没有传递实际值布尔类型的属性分别使用了基本类型和包装类型且属性名使用is开头 null值覆盖导致数据异常内部类数据无法成功拷…

根本记不住MySQL进阶查询语句

1 MySQL进阶查询 1.1 MySQL进阶查询的语句 全文以数据库location和Store_Info为实例 ---- SELECT ----显示表格中一个或数个字段的所有数据记录 语法&#xff1a;SELECT "字段" FROM "表名"; select 列名 from 表名 ; ---- DISTINCT ----不显示重复的数…

使用KVM命令集管理虚拟机

14.2.1案例分析 案例环境使用一台物理机器&#xff0c;一台服务器安装CentOS7.3的64位系统&#xff08;即node01&#xff09;&#xff0c;rhel7.1是在宿主机node01中安装的虚拟机。 14.2.2案例实施 1.安装Linux虚拟机 安装过程同上一案例&#xff0c;使用Xshell 远程控制node0…

视频号上怎么开店带货?门槛和注意事项,如下所示

我是王路飞。 视频号上现在也可以开店带货了&#xff08;严格来说从22年就可以了&#xff09;。 我们团队是在22年9月份开始入局视频号电商这个赛道的&#xff0c;在此之前是专注于抖店&#xff0c;目前两个项目都在做。 今天不聊抖店&#xff0c;主要说下视频号上开店带货的…

Win10电脑关闭OneDrive自动同步的方法

在Win10电脑操作过程中&#xff0c;用户想要关闭OneDrive的自动同步功能&#xff0c;但不知道具体要怎么操作&#xff1f;首先用户需要打开OneDrive&#xff0c;然后点击关闭默认情况下将文档保存到OneDrive选项保存&#xff0c;最后关闭在这台电脑上同步设置保存就好了。接下来…

Flink 维表关联方案

Flink 维表关联方案 1、Flink DataStream 关联维表 1&#xff09;概述 1.分类 实时数据库查找关联&#xff08;Per-Record Reference Data Lookup&#xff09; 预加载维表关联&#xff08;Pre-Loading of Reference Data&#xff09; 维表变更日志关联&#xff08;Refere…

微信小程序+前后端开发学习材料

目录结构 全局文件 1.app.json 文件 用来对微信小程序进行全局配置&#xff0c;决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。文件内容为一个 JSON 对象。 1.1 page用于指定小程序由哪些页面组成&#xff0c;每一项都对应一个页面的 路径&#xff08;含文…

【数值分析】Hermite插值

4. Hermite插值 理论和应用中提出的某些插值问题&#xff0c;要求插值函数 p ( x ) {p(x)} p(x) 具有一定的光滑度&#xff0c;即在插值节点处满足一定的导数条件&#xff0c;这类插值问题称为Hermite插值问题。题目大多以三次Hermite插值为主。三次Hermite插值需要四个条件&…

Leetcode的AC指南 —— 字符串/卡码网:55. 右旋字符串

摘要&#xff1a; Leetcode的AC指南 —— 字符串/卡码网&#xff1a;55. 右旋字符串。题目介绍&#xff1a;字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k&#xff0c;请编写一个函数&#xff0c;将字符串中的后面 k 个字…

grep笔记240103

常用选项&#xff1a;&#xff1a; -i&#xff1a;忽略大小写进行匹配。 -v&#xff1a;反向匹配&#xff0c;只打印不匹配的行。 -n&#xff1a;显示匹配行的行号。 -r&#xff1a;递归查找子目录中的文件。 -l&#xff1a;只打印匹配的文件名。 -c&#xff1a;只打印匹配的行…

整理的6个Linux运维脚本

整理的6个Linux运维脚本 1、统计/etc/passwd 中能登录的用户&#xff0c;并将对应在/etc/shadow 中第二列密码提取2、查看当前连接到本机的远程IP地址3、检测本机当前用户是否为超级管理员&#xff08;root&#xff09;4、检查指定目录下是否存在对应文件5、查找 Linux 系统中的…

QT_02 窗口属性、信号槽机制

QT - 窗口属性、信号槽机制 1. 设置窗口属性 窗口设置 1,标题 2,大小 3,固定大小 4,设置图标在 widget.cpp 文件中&#xff1a; //设置窗口大小,此时窗口是可以拉大拉小的 //1参:宽度 //2参:高度 this->resize(800, 600); //设置窗口标题 this->setWindowTitle("…

使用 Palantir 表征单细胞数据中的细胞状态概率

使用 Palantir 表征单细胞数据中的细胞状态概率 写在前面的概览正文内容摘要Introduction结果马尔可夫过程The Palantir algorithm早期人类造血的景观Palantir 概括了预期的造血趋势与轨迹推理算法的比较 讨论 学习文献 写在前面的概览 Palantir算法主要用于模拟细胞分化的轨迹…

Redis缓存穿透,缓存击穿,缓存雪崩

文章目录 Redis缓存穿透&#xff0c;缓存击穿&#xff0c;缓存雪崩1. 缓存穿透1.1 解决方案1&#xff1a;缓存空数据1.2 解决方案2&#xff1a;使用布隆过滤器1.2.1 布隆过滤器介绍 2. 缓存击穿2.1 解决方案1&#xff1a;互斥锁2.2 解决方案2&#xff1a;逻辑过期 3. 缓存雪崩3…