首先介绍下java的SPI机制
SPI:Service Provider Interface
是一种服务发现机制,SPI的本质是将接口实现类的全限定名配置在文件中,然后又资源加载器读取配置文件,从而加载实现类,这样的好处是可以动态的为接口替换实现类。
JAVA SPI示例
1、首先定义一个接口
public interface Robot {
void sayHello();
}
2、定义两个接口的实现类
public class OptimusPrime implements Robot {
@Override
public void sayHello() {
System.out.println("Hello, I am Optimus Prime.");
}
}
public class Bumblebee implements Robot {
@Override
public void sayHello() {
System.out.println("Hello, I am Bumblebee.");
}
}
3、在META-INF/services下创建一个文件,名称为接口Robot的全限定名,文件的内容为两个实现类的全限定名
org.apache.spi.OptimusPrime
org.apache.spi.Bumblebee
4、编码测试
利用java.util.ServiceLoader类来进行加载
public class JavaSPITest {
@Test
public void sayHello() throws Exception {
ServiceLoader<Robot> serviceLoader = ServiceLoader.load(Robot.class);
System.out.println("Java SPI");
serviceLoader.forEach(Robot::sayHello);
}
}
最后会加载这两个实现类,并且会输出两个实现类的重写方法中的相应的内容
Dubbo SPI
Dubbo的SPI机制在java SPI机制上进行的改进,增加了可以通过传入需要加载的实现类的名称加载相应的实现类。
1、 配置文件路径
META-INF/dubbo
2、配置文件的内容
与java的SPI机制的配置文件内容不同,Dubbo SPI的是采取的键值对的形式,并且在接口上必须注明@SPI的注解
optimusPrime = org.apache.spi.OptimusPrime
bumblebee = org.apache.spi.Bumblebee
3、加载时用到的类及加载方式
加载实现类时用到的类为:com.alibaba.dubbo.common.extension.ExtensionLoader
public class DubboSPITest {
@Test
public void sayHello() throws Exception {
/**
* 首先通过ExtensionLoader创建一个可以加载指定接口的loader
* 然后再通过loader加载指定的实现类,通过文件中健来获取
*/
ExtensionLoader<Robot> extensionLoader =
ExtensionLoader.getExtensionLoader(Robot.class);
Robot optimusPrime = extensionLoader.getExtension("optimusPrime");
optimusPrime.sayHello();
Robot bumblebee = extensionLoader.getExtension("bumblebee");
bumblebee.sayHello();
}
}