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

一文搞懂 Spi 机制

    • 前言
    • class.forName() 里面都发生了啥?
    • Spi 是什么?
    • Spi 如何使用?
    • Spi 代码实现(标准服务厂商)
    • Mysql 驱动厂商
    • 扩展驱动加载测试
    • Spi 机制其他应用场景
    • 可能遇到的问题(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

class.forName() 里面都发生了啥?一文搞懂 Spi 机制_第1张图片

仿照 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 咱们一比一仿制就行。
class.forName() 里面都发生了啥?一文搞懂 Spi 机制_第2张图片
按照同样的目录结构创建 com.example.zzh.spi.java.sql.Driver 文件,然后文件里面指定 com.example.zzh.spi.java.sql.Driver 的实现类就行。
在这里插入图片描述
MysqlDriver 类代码如下,通过加载静态代码块的方式加载驱动。这样依赖驱动就被加载到了标准服务厂那了。

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

图二

扩展驱动加载测试

由于用的 Spring Boot ,在启动类里面显示的调用一下 DriverManager 。触发 DriverManager 类中的静态代码块中的逻辑。
class.forName() 里面都发生了啥?一文搞懂 Spi 机制_第3张图片
可以看到在项目启动之初我们自己的驱动程序就被加载了。后续我们想用 Oracle 驱动的时候,引入 Oracle 的包就行。

截个图 Oracle 的驱动包也是利用 Spi 扩展的。
class.forName() 里面都发生了啥?一文搞懂 Spi 机制_第4张图片

Spi 机制其他应用场景

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

可能遇到的问题(Spi 失效)

如果你用到的是 Spring Boot,但是加载不到我们的 Spi 配置文件,不妨看看编译包里面是否包含我们的 META-INF文件
class.forName() 里面都发生了啥?一文搞懂 Spi 机制_第5张图片
没包含的话配置一下 resources 加载的资源范围就行
class.forName() 里面都发生了啥?一文搞懂 Spi 机制_第6张图片

结语

我是小咸鱼 ,会在以后的日子里跟大家一起学习,一起进步! 觉得文章不错的话,可以在 CSDN 关注我,这样就不会错过很多技术干货啦~

微信公众号刚刚起步,后续创作更多精品内容提供给大家

你可能感兴趣的:(java集合,Spi,机制,java,驱动扩展,插件开发)