Api Spi

2017/12/24

API/SPI

JAVA程序开发中经常说到API和SPI,它们之间究竟有什么区别呢?

API

Application Programming Interface, 一些编程库暴露给开发者调用的接口就是API。一般需要调用者/客户端显式来调用。

SPI

Service Provider Interface, 一般用在框架开发中。正常情况下开发者/客户端不需要关心。主要是方便框架或者系统的扩展性,比如通过实现不同的策略类,自定义类并通过配置文件等方式,动态加载这部分SPI类。如果是Java核心库比如JDBC Driver的SPI接口一般通过Java线程上下文加载器来加载。另外SPI实现类都是框架或者库用来回调的。

SPI实现

java.util.ServiceLoader方式加载SPI实现类

  • 建立目录META-INF/services
  • 以SPI接口全路径名为文件名,文件内容是SPI具体实现类
  • 打jar包
  • 测试项目引入jar
  • 测试代码调用SPI实现类
//将服务声明的文件名称定义为: example.spi.service.IService,与接口名称一致,其中的内容包括:
//example.spi.service.PrintServiceImpl  
//example.spi.service.EchoServiceImpl  

public static void main(String[] args) {  
    //实例化具体类时需要注意对应类有无参构造函数
    ServiceLoader<Service> serviceLoader = ServiceLoader.load(IService.class);  
   
    for (IService service : serviceLoader) {  
        service.printInfo();  
    }  
}

spring factory loader

SpringFactoriesLoader 读取文件 /META-INF/spring.factories

List<Foo> foos = SpringFactoriesLoader.loadFactories(Foo.class, null);

spring.factorie文件中key/value内容没有要求是接口名/实现。比如spring boot自动化配置中的key是org.springframework.boot.autoconfigure.EnableAutoConfiguration 而 values 是 @Configuration注解类

Dubbo ExtensionLoader

Dubbo ExtensionLoader 对比 ServiceLoader 做了一些增强

dubbo约定扩展点配置文件放在classpath下的/META-INF/dubbo,/META-INF/dubbo/internal,/META-INF/services目录下,配置文件名为接口的全限定名,配置文件内容为配置名=扩展实现类的全限定名。

  • 根据key加载实现类,不像ServiceLoader获取接口所有的实现类
  • 增加了对扩展点IoC和AOP的支持,一个扩展点可以直接setter注入其它扩展点

Search

    Table of Contents