简介
Spi(service provider interface)服务发现接口。在面向接口编程中,可以实现插件式的可插拔的选中接口的实现者,来实现高扩展。在dubbo、jdk、jctools等开源项目中都有使用。
在jdk中提供了ServiceLoader来实现Spi。
ServiceLoader简介
官方文档描述
A facility to load implementations of a service. A ServiceLoader is an object that locates and loads service providers deployed in the run time environment at a time of an application's choosing.
使用步骤
- Designing services
- Developing service providers
- Deploying service providers as modules
- Deploying service provider on the class path
- Obaining a service loader
实操
- api 定义服务接口
- api_v1 服务实现v1版本
- api_v2 服务实现v2版本
- spi_test 测试模块
定义接口模块api
public interface HelloService {
void hello();
}
服务实现v1、v2
v1实现
public class HelloServiceImpl implements HelloService {
@Override
public void hello() {
System.out.println("hello...v1");
}
}
v2实现
public class HelloServiceImplV2 implements HelloService {
@Override
public void hello() {
System.out.println("hello...v2");
}
}
测试类spi_test
pom.xml 添加对应的依赖(接口+实现)
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>api_v1</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>api_v2</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
定义MATA-INF/services 配置文件
其中文件名为接口的完全限定名,内容为接口实现类的完全限定名。每个实现类独占一行。
META-INF/services/org.example.api.HelloService
org.example.service.HelloServiceImpl
org.example.service.HelloServiceImplV2
加载对应的服务
通过ServiceLoader::load进行加载对应的服务实现者
public class App
{
public static void main( String[] args )
{
ServiceLoader.load(HelloService.class).forEach(helloService -> {
helloService.hello();
});
}
}
打印结果:
hello...v1
hello...v2
扩展
也可以基于SpringBoot的Conditional来实现Spi,根据配置情况来决定怎么使用扩展。