SPI的全称是Service Provider Interface,翻译过来就是服务提供者的接口,它所实现的其实是一种服务的发现机制。
简单来说,就是服务的调用方定义一个接口规范,可以由不同的服务提供者实现。并且,调用方能够通过某种机制来发现服务提供方,并通过接口调用它的能力。
API中的接口是服务提供者给服务调用者的一个功能列表,而SPI中更多强调的是,服务调用者对服务实现的一种约束,服务提供者根据这种约束实现的服务,可以被服务调用者发现。
说白了,Java中的SPI实现的就是,你按我的接口规范实现服务,我就能通过某种机制为这个接口寻找到这个服务。
eg:
1.创建一个项目,定义一个智能空调的接口
public interface IAircondition {
// 获取型号
String getType();
// 开关
void turnOnOff();
// 调节温度
void adjustTemperature(int temperature);
// 模式变更
void changeModel(int modelId);
}
打包到本地仓库,sringboot项目打包时需要在插件出添加以下代码,否则就算导入包也无法使用接口,详情请看本文章https://www.cnblogs.com/lenve/p/11156340.html的解释。
<configuration>
<skip>
true
</skip>
</configuration>
2.新建一个项目导入刚刚的依赖,实现接口
public class HangingTypeAircondition implements IAricondition {
public HangingTypeAircondition() {
}
public String gettype() {
return "HangingType";
}
public void turnOnOff() {
System.out.println("挂式空调开关");
}
public void adjustTemperature(int temperature) {
System.out.println("挂式空调温度调节" + temperature);
}
public void changeModel(int modelId) {
System.out.println("挂式空调更换模式" + modelId);
}
}
在项目的resources的目录下,创建META-INF/services目录,然后以前面定义的接口名创建文件,并在文件中写入实现类的全限定名。
注意:META-INF/services 必须式这个名字
依旧打包到本地maven仓库。
3.新建一个项目,引入上面两个依赖。测试
public class spitest{
public static void main(String[] args) {
new spitest().turnOn("HangingType");
/*
检测到HangingTypeAircondition
挂式空调开关
*/
}
public void turnOn(String type){
ServiceLoader<IAricondition> load = ServiceLoader.load(IAricondition.class);
for (IAricondition aricondition : load) {
System.out.println("检测到"+aricondition.getClass().getSimpleName());
if (type.equals(aricondition.gettype())){
aricondition.turnOnOff();
}
}
}
}
成功。
454

被折叠的 条评论
为什么被折叠?



