Java SPI 学习记录

Java SPI

文章来源
学习自b站

SPI全称是 Service Provider Interface

他是从java6 开始引入的,是一种基于ClassLoader来发现并加载服务的机制
一个标准的SPI由3个组件构成,分别是:

Service: 是一个公开的接口或抽象类,定义了一个抽象的功能模块
Service Provider: 是Service接口的一个实现类
ServiceLoader: 是SPI机制中的核心组件,负责在运行时发现并加载Service Provider

Java SPI的运行流程

20230803122626
蓝色为jar包内的内容

与Java SPI的作用和设计思想

以JDBC为例来学习

    1. Java SPI在JDBC中的应用

在Java SPI出现之前,程序员们使用Class,forName来加载数据库驱动
如: Class.forName(“com.mysql.jdbc.Driver”)
20230803163239
20230803163551

    1. 那么为什么Class.forName就能加载数据库驱动呢?

这是因为JDBC要求Driver实现类在类加载的时候,能将自身的实例对象自动注册到DriverManager中,从而加载数据库驱动
20230803163756

    1. 那么"com .mysgl.jdbc.Driver",“oracle.jdbc.driver.OracleDriver”
      "com.microsoft.sqlserver.jdbc.SQLServerDriver"这些类名是不是可以写在配置文件里?这样更换数据库驱动时就不用修改代码了?
      例如:
my-app.yml:
    driver-name:com.mysql.jdbc.Driver

但是这样也不够完美,还得记住不同数据库厂商提供的Driver的类名! 所以让数据库厂商来提供配置文件,程序员也省事,数据库厂商也省事,程序员不用了解具体的驱动类名,而厂商也可以轻松升级驱动

    1. 但是由厂商提供配置文件的话,我们怎么去读取它呢?

还记得类ClassLoader么?他除了可以加载类之外,还提供了方法getResource/getResources,可以工具指定的路径,读取classpath中对应的文件,我们可以用它来读取厂商放在Jar包中的配置文件,当然,我们要实现约定好配置文件的路径和格式----这套机制就是SPI
20230803165731
20230803165752

Java SPI的三大规范要素

20230803170930

在JDBC中的对应实现

1.文件路径:
将mysql的jar包解压后,可以看到目录META-INF/services下确实存在一个名为java.sql.Driver的配置文件,文件内容则是mysql的数据库驱动类
20230803170214

2.可以看到mysql的驱动类中确实存在一个默认的无参构造方法
20230803170641

  1. 我们只需要通过maven,将mysql的驱动jar包作为依赖引入后,JDBC就会自动加载mysql的数据库驱动
    20230803170747

总结一下Java SPI

20230803171214

Java SPI与SpringBoot自动配置

20230804113244
SpringBoot与其他框架集成时,不支持扫描注入其他框架的配置类,所以要使用Auto-configuration机制,基于引入的依赖jar包,对SpringBoot应用进行自动配置,换而言之,就是将其它jar包的配置类注入到IOC容器内

20230804113908

20230804114223