Service Provider Interface : 服务提供接口。
面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。
一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。
为了实现在模块装配的时候不用在程序里动态指明,这就需要一种服务发现机制。
java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。
这有点类似IOC的思想,将装配的控制权移到了程序之外。
JavaSPI 实际上是“基于接口的编程+策略模式+配置文件”组合实现的动态加载机制。
1. 先定义一个接口LJSPIService
package com.robinboot.service;
/**
* @Auther: TF12778
* @Date: 2020/3/27 16:56
* @Description:
*/
public interface LJSPIService {
public void prinfMessage();
}
2. 写2个基于接口LJSPIService的实现类:LJPrintfSPIService 和 LJSoutSPIService
package com.robinboot.service.service.Impl;
import com.robinboot.service.LJSPIService;
/**
* @auther: TF12778
* @date: 2020/3/27 16:58
* @description:
*/
public class LJSoutSPIService implements LJSPIService {
@Override
public void prinfMessage() {
System.out.println("SoutSPIService prinfMessage");
}
}
package com.robinboot.service.service.Impl;
import com.robinboot.service.LJSPIService;
/**
* @auther: TF12778
* @date: 2020/3/27 16:57
* @description:
*/
public class LJPrintfSPIService implements LJSPIService {
@Override
public void prinfMessage() {
System.out.println("PrintfSPIService prinfMessage");
}
}
3. 配置文件
创建META-INF.services包,添加以接口LJSPIService的全限定名文件,内容是上面的实现类,如下:
4.测试
@Test
public void SPITest() {
ServiceLoader<LJSPIService> s = ServiceLoader.load(LJSPIService.class);
Iterator<LJSPIService> iterator = s.iterator();
while (iterator.hasNext()) {
LJSPIService search = iterator.next();
search.prinfMessage();
}
}
测试结果: