Dubbo-SPI

SPI

1. 定义

SPI即Service Provider Interface,服务提供接口。

​ 系统中抽象的各个模块,往往有很多不同的实现方案,比如日志模块,xml解析模块,jdbc模块的方案等。面向对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里设计具体的实现类,就违反了可插拔的原则,如果需要替换一种实现,就需要修改代码。

​ 为了实现在模块装配的时候能不在程序里动态指明,就需要一种服务发现机制。JAVA SPI就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将转配的控制权一到程序之外,在模块化设计中这个机制尤其重要。

1.1. Java SPI的约定

​ 当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同事创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过jar包META-INF/services里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。

​ 基于这样一个约定就能很好的找到接口的实现类,而不需要在代码里定制。jdk提供服务实现查找的一个工具类:java.util.ServiceLoader

1.2. 范例
1.3. Demo

定义接口类

package cn.test.spi;

public interface Animal {
   
  String cry();
}

接口实现类

package cn.test.spi;

public class Cat implements Animal {
   
    public String cry() {
        return "cat cry...";
    }
}

public class Dog implements Animal {
   
    public String cry() {
        return "dog cry...";
    }
}

运行

package cn.test.spi;

import java.util.Iterator;
import java.util.ServiceLoader;

public class TestAnimal {
   
    public static void main(String[] args) {
        ServiceLoader loader = ServiceLoader.load(Animal.class);
        Iterator iterator = loader.iterator();
        while (iterator.hasNext()) {
            Animal animal = iterator.next();
            System.out.println(animal.getClass());
            System.out.println(animal.cry());
        }
    }
}

其中,在META-INF/services目录中创建文件cn.test.spi.Animal,内容为cn.test.spi.Cat

输出结果为:

class cn.test.spi.Cat
cat cry...

以上及时基于Java SPI机制查找服务的实现。

2. Dubbo基于SPI思想实现

Dubbo对Java SPI发现机制加强而来。

  1. Java SPI标准的SPI会一次性实例化扩展点的所有实现,如果扩展实现很耗时,但如果没有用到也加载,会资源;还有如果实现类缺失依赖,实例化直接出错;
  2. 如果扩展点记载失败,连扩展点的名称都拿不到;
  3. 增加了IOC的支持,一个扩展点可以直接setter注入其他扩展点;

优先关注dubbo-common子项目的com.alibaba.dubbo.common.extension类包。

2.1. SPI接口定

你可能感兴趣的:(源码,编程,java,dubbo,源码)