浅谈jdk-spi与dubbo-spi
关于SPI:
关于SPI的概念,此处不再过多撰述,一句话:接口的实现的发现机制
我们直接来看两个案例
1. jdk-spi示例:
定义一个接口:Animal
public interface Animal {
void say();
}
定义两个实现类
public class Cat implements Animal {
@Override
public void say() {
System.out.println("小猫");
}
}
public class Dog implements Animal {
@Override
public void say() {
System.out.println("小狗");
}
}
resource/META-INF/services 下创建一个文件:com.kl.dubbotest.jdkspi.Animal,内容如下
com.kl.dubbotest.jdkspi.Dog
com.kl.dubbotest.jdkspi.Cat
编写test
public class SpiTest {
public static void main(String[] args) {
ServiceLoader<Animal> serviceLoader = ServiceLoader.load(Animal.class);
for (Animal animal: serviceLoader){
animal.say();
}
}
}
测试结果,如下:
2. dubbo-spi示例:
dubbo-spi必须要在扩展接口上加@SPI注解,所以Animal接口需要加上
resource/META-INF/dubbo 下创建一个文件:com.kl.dubbotest.dubbospi.Animal,内容如下
dog = com.kl.dubbotest.dubbospi.Dog
cat = com.kl.dubbotest.dubbospi.Cat
编写test
@Test
public void animalSpi() {
ExtensionLoader<Animal> extensionLoader = ExtensionLoader.getExtensionLoader(Animal.class);
Animal animal = extensionLoader.getExtension("cat");
animal.say();
animal = extensionLoader.getExtension("dog");
animal.say();
}
测试结果,如下:
3. jdk-spi优缺点分析
优点:
扩展功能实现了解耦
缺点:
(1)浪费:将接口的实现类全部加载并实例化一遍,不想用某些实现类,它也被加载并实例化了,
(2)不灵活:不能获取指定的实现类,只能通过Iterator形式获取
(3)线程不安全:多线程使用ServiceLoader类的实例是不安全的
所以:dubbo说要自己干一套出来