SPI

发布时间 2023-11-28 16:11:22作者: anpeiyong

概述

SPI(Service Provider Interface)

JDK内置的一种 服务提供发现机制

用来 启用框架扩展和替换组件

 

服务的提供者提供了一种接口的实现之后,需要在classpath下的META-INF/services/目录里创建一个以服务接口命名的文件,这个文件里的内容就是这个接口的具体的实现类;

当其他的程序需要这个服务的时候,就可以通过查找这个jar包(一般都是以jar包做依赖)的META-INF/services/中的配置文件,配置文件中有接口的具体实现类名,可以根据这个类名进行加载实例化,就可以使用该服务了;

 

JDK中查找服务的实现的工具类是:java.util.ServiceLoader

ServiceLoader.load(Search.class)在加载某接口时,会去META-INF/services下找接口的全限定名文件,再根据里面的内容加载相应的实现类;

 

如何使用SPI机制

1、定义标准

  如java.sql.Driver

2、不同服务提供方实现

  如MySQL的com.mysql.jdbc.Driver实现,在MySQL的mysql-connector-java-5.1.46.jar中的META-INF/service中有个java.sql.Driver的文件,里面的内容是对应的MySQLDriver实现;

    

3、应用

  ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);

 

广泛应用

jdbc Driver

java中定义了java.sql.Driver,由不同的数据库厂商提供实现;

MySQL的mysql-connector-java-5.1.46.jar中的META-INF/service中有个java.sql.Driver的文件,里面的内容是对应的MySQLDriver实现;

 

springboot中的SPI机制

在springboot的自动装配过程中,最终会加载META-INF/spring.factories文件,而加载的过程是由SpringFactoriesLoader加载的。

从CLASSPATH下的每个Jar包中搜寻所有META-INF/spring.factories配置文件,然后将解析properties文件,找到指定名称的配置后返回。

需要注意的是,其实这里不仅仅是会去ClassPath路径下查找,会扫描所有路径下的Jar包,只不过这个文件只会在Classpath下的jar包中;

...