【基础篇】七、线程上下文类加载器打破双亲委派机制

文章目录

  • 1、SPI机制
  • 2、JDBC案例之SPI机制
  • 3、打破双亲委派机制:线程上下文类加载器
  • 4、打破双亲委派机制:osgi模块化
  • 5、JDK9之后的类加载器
  • 6、小总结

1、SPI机制

SPI,Service Provider Interface,是JDK内置的一种服务提供发现机制。大致流程:

  • 相关组织定义好接口标准并对外提供
  • 第三方去针对接口写实现类,并将信息写在META-INF/services/${interface_name},文件内容是实现类全类名
  • 用户使用JDK提供的ServiceLoader加载(jar里的)实现类

写个小Demo直观感受下SPI,定义对外接口:

public interface SpiInterface {void helloSpi();}

其他类写实现类(这里接口和实现类放同一个jar中了,一般来说写接口和写实现的是两种角色):

public class SpiClass1 implements SpiInterface {@Overridepublic void helloSpi() {System.out.println("hello SpiClass1...");}
}
public class SpiClass2 implements SpiInterface {@Overridepublic void helloSpi() {System.out.println("hello SpiClass2...");}
}

写文件:

在这里插入图片描述

//内容
com.plat.impl.SpiClass1
com.plat.impl.SpiClass2

测试模块中引入上面的这个jar:

<dependency><groupId>com.plat</groupId><artifactId>demo</artifactId><version>0.0.1</version>
</dependency>

尝试加载:

public class SpiTest {public static void main(String[] args) {ServiceLoader<SpiInterface> serviceLoader = ServiceLoader.load(SpiInterface.class);for (SpiInterface spiClass : serviceLoader) {System.out.println(spiClass);spiClass.helloSpi();}}
}

成功获取到接口的两个实现类:

在这里插入图片描述

2、JDBC案例之SPI机制

JDBC使用DriverManager类来完成不同数据库厂商的驱动注册:

/获取连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testDB","root","95279527");

DriverManager位于JDK的rt.jar包,由启动类加载器去加载,而引入的第三方jar包归应用程序类加载器管。DriverManager又如何知道jar中要加载哪个驱动类?看下DriverManager类的源码,其中有一段静态代码块:

在这里插入图片描述

往下跟进loadInitialDrivers方法:

在这里插入图片描述

断点看下值,成功拿到MySQL驱动的类名:

在这里插入图片描述

即SPI机制去加载这个接口的实现类,然后用迭代器去遍历所有jar包种满足条件的类名。而MySQL驱动的jar中已按SPI流程写好了实现类和名为java.sql.Driver的文件:

在这里插入图片描述

到此,整个JDBC的流程为:

在这里插入图片描述

拿到jar包中驱动类的类名了,但这个类得靠应用程序类加载器去加载,那应用程序类加载器从哪儿来? ⇒ SPI过程能拿到应用程序类加载器,是因为SPI使用了线程上下文中保存的类加载器:

在这里插入图片描述

而线程上下文类加载器通常为应用程序类加载器(一个线程创建完之后,JVM底层会将应用程序类加载器放到线程上下文中):

//获取线程上下文类加载器
ClassLoader c = Thread.currentThread.getContextClassLoader();
//设置线程上下文的类加载器为自定义类加载器
Thread.currentThread().setContextClassLoader(new BreakClassLoader1());
//com.plat.broken.BreakClassLoader1@6537cf78
System.out.println(Thread.currentThread().getContextClassLoader());

ps:对于MySQL的驱动类,其加载过程中会自动注册驱动:

在这里插入图片描述

3、打破双亲委派机制:线程上下文类加载器

JDBC案例中,启动类加载器要委托它的下级应用程序类加载器去加载一个类,与双亲委派机制的自下而上委派不符合,因此才说打破了双亲委派机制,但其实这两块都各自满足双亲委派机制,单看DriverManager,其就应该由启动类加载器干,但看Jar中的MySQL驱动类,其也本该由应用程序类加载器干。

在这里插入图片描述

4、打破双亲委派机制:osgi模块化

历史上,OSGi模块化框架。它存在同级之间的类加载器的委托加载:
在这里插入图片描述

5、JDK9之后的类加载器

JDK8及之前的版本中,扩展类加载器和应用程序类加载器的源码位于rt.jar包中的sun.misc.Launcher.java。
在这里插入图片描述
这两个类加载器都继承自URLClassLoader,URLClassLoader是根据某一个特定的目录去找到jar包以及jar包中的字节码文件,所以,JDK8及以前,是按照jar包的位置去加载字节码文件的。JDK9引入了module的概念,之前的包放入到了jmods目录下的jmod文件中,对应的,类加载器也由原来的从jar包中加载改为了去jmod文件中加载:

在这里插入图片描述

类加载器的变化:

  • 启动类加载器使用Java编写,位于jdk.internal.loader.ClassLoaders类中,但java代码中获取启动类加载器对象依然为null
    在这里插入图片描述

  • 扩展类加载器被替换成了平台类加载器(Platform Class Loader),平台类加载器遵循模块化方式加载字节码文件,之前扩展类加载器继承自URLClassLoader,现在继承自BuiltinClassLoader
    在这里插入图片描述

6、小总结

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

NModbus-一个C#的Modbus协议库实现

NModbus-一个基于C#实现的Modbus通信协议库 最近在学习C#的时候&#xff0c;因为之前做过环保设备时使用C做过环保设备采集使用到了Modbus协议&#xff0c;当时看了一下基于C语言开发的libmodbus库。所以特意搜索看了一下C#下有什么Modbus协议库&#xff0c;在Github上面找了一…

Strateg策略模式(组件协作)

策略模式&#xff08;组件协作&#xff09; 链接&#xff1a;策略模式实例代码 注解 目的 正常情况下&#xff0c;一个类/对象中会包含其所有可能会使用的内外方法&#xff0c;但是一般情况下&#xff0c;这些常使用的类都是由不同的父类继承、组合得来的&#xff0c;来实现…

Feign远程调用

Feign远程调用 Fegin的使用步骤如下&#xff1a; 1&#xff09;引入依赖 我们在order-service服务的pom文件中引入feign的依赖&#xff1a; <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign&…

SadTalker数字人增加视频输出mp4质量精度

最近在用数字人简易方案&#xff0c;看到了sadtalker虽然效果差&#xff0c;但是可以作为一个快速方案&#xff0c;没有安装sd的版本&#xff0c;随便找了个一键安装包 设置如上 使用倒是非常简单&#xff0c;但是出现一个问题&#xff0c;就是输出的mp4都出马赛克了 界面上却…

基于图搜索的自动驾驶规划算法 - BFS,Dijstra,A*

本文将讲解BFS&#xff0c;Dijstra&#xff0c;A*&#xff0c;动态规划的算法原理&#xff0c;不正之处望读者指正&#xff0c;希望有兴趣的读者能在评论区提出一些这些算法的面试考点&#xff0c;共同学习&#xff0c;一起进步 0 图论基础 图有三种&#xff1a;无向图、有向…

基于 Linux 的批量上传本地 Git 仓库到 Github 的实践

基于 Linux 的批量上传本地 Git 仓库到 Github 的实践 一、需求二、上传本地 Git 仓库2.1 初始版本2.2 优化版本 三、 GitHub 创建空仓库3.1 初始版本3.2 优化版本 四、Gitee 创建空仓库 一、需求 app目录下的每个文件夹都是一个git仓库&#xff0c;如何使用shell脚本将所有gi…

Java核心知识点1-java和c++区别、隐式和显示类型转换

java和c区别 java通过虚拟机实现跨平台特性&#xff0c;但c依赖于特定的平台。java没有指针&#xff0c;它的引用可以理解为安全指针&#xff0c;而c和c一样具有指针。java支持自动垃圾回收&#xff0c;而c需要手动回收。java不支持多重继承&#xff0c;只能通过实现多个接口来…

自动驾驶学习笔记(二十三)——车辆控制模型

#Apollo开发者# 学习课程的传送门如下&#xff0c;当您也准备学习自动驾驶时&#xff0c;可以和我一同前往&#xff1a; 《自动驾驶新人之旅》免费课程—> 传送门 《Apollo开放平台9.0专项技术公开课》免费报名—>传送门 文章目录 前言 运动学模型 动力学模型 总结…

Prometheus快速入门实战

介绍 prometheus 受启发于 Google 的 Brogmon 监控系统&#xff08;相似 kubernetes 是从 Brog 系统演变而来&#xff09;。2016 年 5 月继 kubernetes 之后成为第二个加入 CNCF 基金会的项目&#xff0c;同年 6 月正式发布 1.0 版本。2017 年底发布基于全新存储层的 2.0 版本…

nginx设置跨域访问

目录 一&#xff1a;前端请求 二&#xff1a;后端设置 网站架构前端使用jquery请求&#xff0c;后端使用nginxphp-fpm 一&#xff1a;前端请求 <script> $.getJSON(http://nngzh.youjoy.com/cc.php, { openid: sd, }, function(res) { alert(res); if(res.code 0) …

华锐视点为广汽集团打造VR汽车在线展厅,打破地域限制,尽享购车乐趣

随着科技的飞速发展&#xff0c;我们正在进入一个全新的时代——元宇宙时代。元宇宙是一个虚拟的世界&#xff0c;它不仅能够模拟现实世界&#xff0c;还能够创造出现实世界无法实现的事物。而汽车行业作为人类生活的重要组成部分&#xff0c;也在积极探索与元宇宙的融合&#…

CompletableFuture是什么?以及CompletableFuture的作用

文章目录 CompletableFuture 今天我们来聊聊 CompletableFuture CompletableFuture CompletableFuture 是 JDK1.8 里面引入的一个基于事件驱动的异步回调类。 简单来说&#xff0c;就是当使用异步线程去执行一个任务的时候&#xff0c;我们希望在任务结束以后触发一个后续的动作…

jmeter函数助手-常用汇总

一.函数助手介绍 1.介绍及作用 介绍&#xff1a; jmeter自带的一个特性&#xff0c;可以通过指定的函数规则创建后进行调用该函数&#xff0c;在后续接口请求参数中进行调用 作用 &#xff08;1&#xff09;做参数化。 2.如何使用 jmeter工具栏-->工具-->函数助手…

车牌识别技术,如何用python识别车牌号

目录 一.前言 二.运行环境 三.代码 四.识别效果 五.参考 一.前言 车牌识别技术&#xff08;License Plate Recognition, LPR&#xff09;在交通计算机视觉&#xff08;Computer Vision, CV&#xff09;领域具有非常重要的研究意义。以下是该技术的一些扩展说明&#xff1…

VSCODE 修改Test模式下的的java jvm堆内存大小

在settings.json中添加如下语句 "java.test.config": {"vmArgs": ["-Xmx12G"]},

《HelloGitHub》第 93 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 Python、Java、Go、C/C、Swift...让你在短时间内…

超简单实用,推荐的深度学习科研必备网站(轻松找论文,代码项目,写论文综述)

一个非常有用的深度学习必备网站 网址推荐 接触新方向需要了解的内容1.在某一个研究方向下&#xff0c;有哪些算法模型可以用&#xff1f;不同算法之间效果对比如何&#xff1f;2.在某一个研究方向下&#xff0c;到底有哪些论文&#xff0c;模型是可以用的&#xff1f;3.在某一…

【办公技巧】怎么批量提取文件名到excel

Excel是大家经常用来制作表格的文件&#xff0c;比如输入文件名&#xff0c;如果有大量文件需要输入&#xff0c;用张贴复制或者手动输入的方式还是很费时间的&#xff0c;今天和大家分享如何批量提取文件名。 打开需要提取文件名的文件夹&#xff0c;选中所有文件&#xff0c…

【VS】NETSDK1045 当前 .NET SDK 不支持将 .NET 6.0 设置为目标。

问题描述 报错 NETSDK1045 严重性代码说明项目文件行禁止显示状态错误NETSDK1045当前 .NET SDK 不支持将 .NET 6.0 设置为目标。请将 .NET 5.0 或更低版本设置为目标&#xff0c;或使用支持 .NET 6.0 的 .NET SDK 版本。RCSoftDrawMicrosoft.NET.TargetFrameworkInference.ta…

Linux stress命令---压力测试

一、使用场景 CPU压力测试 内存压力测试 磁盘IO测试 Swap可用性测试 二、语法及常用参数 stress [选项] [进程数] -?, --help&#xff1a;显示帮助信息 --version&#xff1a;显示版本信息 -v, --verbose&#xff1a;详细输出 -q, --quiet&#xff1a;静默输出 -t, --timeout&…