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

相关文章

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

一文详解SpringBoot响应压缩功能的配置与优化

《一文详解SpringBoot响应压缩功能的配置与优化》SpringBoot的响应压缩功能基于智能协商机制,需同时满足很多条件,本文主要为大家详细介绍了SpringBoot响应压缩功能的配置与优化,需... 目录一、核心工作机制1.1 自动协商触发条件1.2 压缩处理流程二、配置方案详解2.1 基础YAML

java中反射(Reflection)机制举例详解

《java中反射(Reflection)机制举例详解》Java中的反射机制是指Java程序在运行期间可以获取到一个对象的全部信息,:本文主要介绍java中反射(Reflection)机制的相关资料... 目录一、什么是反射?二、反射的用途三、获取Class对象四、Class类型的对象使用场景1五、Class

一文详解如何从零构建Spring Boot Starter并实现整合

《一文详解如何从零构建SpringBootStarter并实现整合》SpringBoot是一个开源的Java基础框架,用于创建独立、生产级的基于Spring框架的应用程序,:本文主要介绍如何从... 目录一、Spring Boot Starter的核心价值二、Starter项目创建全流程2.1 项目初始化(

一文带你了解SpringBoot中启动参数的各种用法

《一文带你了解SpringBoot中启动参数的各种用法》在使用SpringBoot开发应用时,我们通常需要根据不同的环境或特定需求调整启动参数,那么,SpringBoot提供了哪些方式来配置这些启动参... 目录一、启动参数的常见传递方式二、通过命令行参数传递启动参数三、使用 application.pro

一文带你深入了解Python中的GeneratorExit异常处理

《一文带你深入了解Python中的GeneratorExit异常处理》GeneratorExit是Python内置的异常,当生成器或协程被强制关闭时,Python解释器会向其发送这个异常,下面我们来看... 目录GeneratorExit:协程世界的死亡通知书什么是GeneratorExit实际中的问题案例

一文详解SQL Server如何跟踪自动统计信息更新

《一文详解SQLServer如何跟踪自动统计信息更新》SQLServer数据库中,我们都清楚统计信息对于优化器来说非常重要,所以本文就来和大家简单聊一聊SQLServer如何跟踪自动统计信息更新吧... SQL Server数据库中,我们都清楚统计信息对于优化器来说非常重要。一般情况下,我们会开启"自动更新

一文详解kafka开启kerberos认证的完整步骤

《一文详解kafka开启kerberos认证的完整步骤》这篇文章主要为大家详细介绍了kafka开启kerberos认证的完整步骤,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、kerberos安装部署二、准备机器三、Kerberos Server 安装1、配置krb5.con

一文详解Nginx的强缓存和协商缓存

《一文详解Nginx的强缓存和协商缓存》这篇文章主要为大家详细介绍了Nginx中强缓存和协商缓存的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、强缓存(Strong Cache)1. 定义2. 响应头3. Nginx 配置示例4. 行为5. 适用场景二、协商缓存(协

Nginx之upstream被动式重试机制的实现

《Nginx之upstream被动式重试机制的实现》本文主要介绍了Nginx之upstream被动式重试机制的实现,可以通过proxy_next_upstream来自定义配置,具有一定的参考价值,感兴... 目录默认错误选择定义错误指令配置proxy_next_upstreamproxy_next_upst