左眼用来忘记你,右眼用来回忆你,不是我不爱你,只是哥一直在你心里,大家好我是一只摆烂的小咸鱼,今天给大家介绍 Java Spi 机制原理,以及 Spi 机制在我们身边的应用场景。
答:显示加载数据库驱动
答:Spi 是 Jdk 内置的服务动态发现替换的机制,一种解耦的思想。
答:在 ClassPath 路径下的 META-INF/services 文件夹创建这么一个文件,
以接口的全限定名来命名文件名,文件里面写该接口的实现名。然后通过调用
ServiceLoader.load(限定接口),即可加载到所有接口实现类。这个实现类可以由多个服务商提供,但是客户只需调用标准服务接口即可。当客户想替换服务商时,替换实现类即可。而这个实现类由每个服务商维护,完全不用客户操心。客户只管用就行。代码耦合性很低。
手撕一遍源码加深理解,就拿最常用的 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 驱动等。接下来看下驱动厂商是如何做的
看源码包,就是在 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 扩展的。
Spring Boot 自动装配也是用到了 Spi 机制。
手把手debug自动装配源码、顺带弄懂了@Import等相关的源码(全文3w字、超详细)
如果你用到的是 Spring Boot,但是加载不到我们的 Spi 配置文件,不妨看看编译包里面是否包含我们的 META-INF文件
没包含的话配置一下 resources 加载的资源范围就行
我是小咸鱼 ,会在以后的日子里跟大家一起学习,一起进步! 觉得文章不错的话,可以在 CSDN 关注我,这样就不会错过很多技术干货啦~
🌸🌸微信公众号刚刚起步,后续创作更多精品内容提供给大家