- 什么是java SPI
SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。目前市面上有很多框架都是用它来做服务的扩展发现,大家耳熟能详的如dubbo、JDBC、日志框架都有用到。 - 简单实现
(1)在demo1 中定义一个sayhell()的接口,并将Api打包到本地仓库。如下,public interface SayHello { void hello(String name); }
(2)在Chinese-hello中依赖上述api,并实现接口。代码如下:
public class ChineseHello implements SayHello { @Override public void hello(String name) { System.out.println("你好" + name); } }
(3) 然后在classespath下创建 META-INF/services 文件夹。并创建一个文件,名称为 接口(SayHello)的全限定名 com.pxc.api.SayHello。文件内容为实现类的全限定的类名,com.pxc.spi.ChineseHello。同样在写一个实现类EnglishHello
(4)使用ServiceLoader来调用
public static void main(String[] args) { ServiceLoader<SayHello> sayHellos = ServiceLoader.load(SayHello.class); sayHellos.forEach(sayHello -> sayHello.hello("pxc")); }
执行结果:
说明:如果两个实现的jar包都依赖,全部都会加载 - java SPI的规范
1. 需要在classpath下创建一个目录,该目录命名必须是:META-INF/services
2. 在该目录下创建一个文件,该文件需要满足以下几个条件
a) 文件名必须是扩展的接口的全路径名称
b) 文件内部描述的是该扩展接口的所有实现类
c) 文件的编码格式是UTF-8
3. 通过java.util.ServiceLoader的加载机制来发现