class.forName() 里面都发生了啥?一文搞懂 Spi 机制

2023-10-13 17:05

本文主要是介绍class.forName() 里面都发生了啥?一文搞懂 Spi 机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一文搞懂 Spi 机制

    • 前言
    • class.forName() 里面都发生了啥?
    • Spi 是什么?
    • Spi 如何使用?
    • Spi 代码实现(标准服务厂商)
    • Mysql 驱动厂商
    • 扩展驱动加载测试
    • Spi 机制其他应用场景
    • 结语

前言

左眼用来忘记你,右眼用来回忆你,不是我不爱你,只是哥一直在你心里,大家好我是一只摆烂的小咸鱼,今天给大家介绍 Java Spi 机制原理,以及 Spi 机制在我们身边的应用场景。

class.forName() 里面都发生了啥?

答:显示加载数据库驱动

Spi 是什么?

答:Spi 是 Jdk 内置的服务动态发现替换的机制,一种解耦的思想。

Spi 如何使用?

答:在 ClassPath 路径下的 META-INF/services 文件夹创建这么一个文件,
以接口的全限定名来命名文件名,文件里面写该接口的实现名。然后通过调用
ServiceLoader.load(限定接口),即可加载到所有接口实现类。
这个实现类可以由多个服务商提供,但是客户只需调用标准服务接口即可。当客户想替换服务商时,替换实现类即可。而这个实现类由每个服务商维护,完全不用客户操心。客户只管用就行。代码耦合性很低。

Spi 代码实现(标准服务厂商)

手撕一遍源码加深理解,就拿最常用的 com.mysql.cj.jdbc.Driver 驱动是如何被加载的举例,仿照 Java.sql.Driver 源码,编写我们自己的标准驱动接口 com.example.zzh.spi.java.sql.Driver

在这里插入图片描述

仿照 Java.sql.DriverManager 源码,编写我们自己的 DriverManager 类,当 DriverManager 实例化的时候,静态代码块会被调用,执行我们的 loadInitialDrivers 方法(去加载驱动),至于加载哪些驱动,里面会去扫描 ClassPath 路径下的 META-INF/services 里面的文件,实例化所有com.example.zzh.spi.java.sql.Driver 的接口实现类,这些实现类交付给各大驱动厂商扩展例如:Oracle 驱动、Mysql 驱动等。接下来看下驱动厂商是如何做的

在这里插入图片描述

Mysql 驱动厂商

看源码包,就是在 ClassPath 路径下的 META-INF/services 文件夹下面创建了一个 java.sql.Driver 文件,ok 咱们一比一仿制就行。
在这里插入图片描述
按照同样的目录结构创建 com.example.zzh.spi.java.sql.Driver 文件,然后文件里面指定 com.example.zzh.spi.java.sql.Driver 的实现类就行。
在这里插入图片描述
MysqlDriver 类代码如下,通过加载静态代码块的方式加载驱动。这样依赖驱动就被加载到了标准服务厂那了。
在这里插入图片描述

🌸🌸文件名定义规范请查阅 Spi 如何使用章节🌸🌸

图二

扩展驱动加载测试

由于用的 Spring Boot ,在启动类里面显示的调用一下 DriverManager 。触发 DriverManager 类中的静态代码块中的逻辑。
在这里插入图片描述
可以看到在项目启动之初我们自己的驱动程序就被加载了。后续我们想用 Oracle 驱动的时候,引入 Oracle 的包就行。
在这里插入图片描述
截个图 Oracle 的驱动包也是利用 Spi 扩展的。
在这里插入图片描述

Spi 机制其他应用场景

Spring Boot 自动装配也是用到了 Spi 机制。
手把手debug自动装配源码、顺带弄懂了@Import等相关的源码(全文3w字、超详细)

结语

🌸🌸如果本文对您有帮助 🌸🌸
🌸🌸不妨点个免费的赞或者关注 🌸🌸
🌸🌸这将成为我前进的最大动力🌸🌸

🍉🍉微信公众号刚刚起步,后续有时间将录个视频放到公众号上面,时长大概 10 分钟左右,并且顺带带读者看一下源码,还有空的话会将以往所有写过的源码解读博文,也以视频的方式放到上面去,可以私我先转义哪一篇博文哦!!!🍉🍉

在这里插入图片描述

这篇关于class.forName() 里面都发生了啥?一文搞懂 Spi 机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/204660

相关文章

一文详解如何在Vue3中封装API请求

《一文详解如何在Vue3中封装API请求》在现代前端开发中,API请求是不可避免的一部分,尤其是与后端交互时,下面我们来看看如何在Vue3项目中封装API请求,让你在实现功能时更加高效吧... 目录为什么要封装API请求1. vue 3项目结构2. 安装axIOS3. 创建API封装模块4. 封装API请求

嵌入式Linux驱动中的异步通知机制详解

《嵌入式Linux驱动中的异步通知机制详解》:本文主要介绍嵌入式Linux驱动中的异步通知机制,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、异步通知的核心概念1. 什么是异步通知2. 异步通知的关键组件二、异步通知的实现原理三、代码示例分析1. 设备结构

JVM垃圾回收机制之GC解读

《JVM垃圾回收机制之GC解读》:本文主要介绍JVM垃圾回收机制之GC,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、死亡对象的判断算法1.1 引用计数算法1.2 可达性分析算法二、垃圾回收算法2.1 标记-清除算法2.2 复制算法2.3 标记-整理算法2.4

一文带你搞懂Redis Stream的6种消息处理模式

《一文带你搞懂RedisStream的6种消息处理模式》Redis5.0版本引入的Stream数据类型,为Redis生态带来了强大而灵活的消息队列功能,本文将为大家详细介绍RedisStream的6... 目录1. 简单消费模式(Simple Consumption)基本概念核心命令实现示例使用场景优缺点2

一文详解Java异常处理你都了解哪些知识

《一文详解Java异常处理你都了解哪些知识》:本文主要介绍Java异常处理的相关资料,包括异常的分类、捕获和处理异常的语法、常见的异常类型以及自定义异常的实现,文中通过代码介绍的非常详细,需要的朋... 目录前言一、什么是异常二、异常的分类2.1 受检异常2.2 非受检异常三、异常处理的语法3.1 try-

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

一文带你搞懂Python中__init__.py到底是什么

《一文带你搞懂Python中__init__.py到底是什么》朋友们,今天我们来聊聊Python里一个低调却至关重要的文件——__init__.py,有些人可能听说过它是“包的标志”,也有人觉得它“没... 目录先搞懂 python 模块(module)Python 包(package)是啥?那么 __in

一文详解如何在Python中从字符串中提取部分内容

《一文详解如何在Python中从字符串中提取部分内容》:本文主要介绍如何在Python中从字符串中提取部分内容的相关资料,包括使用正则表达式、Pyparsing库、AST(抽象语法树)、字符串操作... 目录前言解决方案方法一:使用正则表达式方法二:使用 Pyparsing方法三:使用 AST方法四:使用字

电脑死机无反应怎么强制重启? 一文读懂方法及注意事项

《电脑死机无反应怎么强制重启?一文读懂方法及注意事项》在日常使用电脑的过程中,我们难免会遇到电脑无法正常启动的情况,本文将详细介绍几种常见的电脑强制开机方法,并探讨在强制开机后应注意的事项,以及如何... 在日常生活和工作中,我们经常会遇到电脑突然无反应的情况,这时候强制重启就成了解决问题的“救命稻草”。那

SpringRetry重试机制之@Retryable注解与重试策略详解

《SpringRetry重试机制之@Retryable注解与重试策略详解》本文将详细介绍SpringRetry的重试机制,特别是@Retryable注解的使用及各种重试策略的配置,帮助开发者构建更加健... 目录引言一、SpringRetry基础知识二、启用SpringRetry三、@Retryable注解