最近在阅读Dubbo框架源代码时,经常看到@Spi,查了一下SPI: Service Provider Interface : 服务提供接口。
Dubbo的spi是该框架的核心和强大之处,可以实现组件插拔式开发,其思想来源于java的spi,我们先来看一下java的spi是怎么实现的。
JavaSPI :“基于接口的编程+策略模式+配置文件”组合实现的动态加载机制。步骤:
1、定义一组接口, 假设是 autocomplete.PrefixMatcher;
2、写出接口的一个或多个实现(autocomplete.EffectiveWordMatcher, autocomplete.SimpleWordMatcher);
3、 在 src/main/resources/ 下建立 /META-INF/services 目录, 新增一个以接口命名的文件 autocomplete.PrefixMatcher, 内容是要应用的实现类(autocomplete.EffectiveWordMatcher 或 autocomplete.SimpleWordMatcher 或两者);
4、使用 ServiceLoader 来加载配置文件中指定的实现。
下面通过一个简单的Demo来看一下是怎么实现的:
1、首先写一个接口
package spi;
public interface DubboServiceTest{
public void sayHello();
}
2、然后写2个实现类
package spi;
public class RedServiceimplements DubboServiceTest {
public void sayHello() {
System.out.println("您好!我是一个红色的灯");
}
}
另一个:
package spi;
public class YellowServiceimplements DubboServiceTest{
public void sayHello(){
System.out.println("您好!我是一个黄色的灯");
}
}
3、新建一个配置文件,文件名就是接口的全限定名称,文件内容就是实现类的路径名称
spi.RedService
spi.YellowService
4、新建一个启动类,用ServiceLoader类加载配置文件,读取实现方法:
package spi;
import java.util.Iterator;
import java.util.ServiceLoader;
public class ServiceMain {
public static void main(String[] args) {
ServiceLoader spiLoader = ServiceLoader.load(DubboServiceTest.class);
Iterator iteratorSpi = spiLoader.iterator();
while (iteratorSpi.hasNext()){
DubboServiceTest dubboServiceTest = iteratorSpi.next();
dubboServiceTest.sayHello();
}
}
}
最后启动主类,在控制台看到打印信息如下: