Dubbo SPI机制

一个合格的开源框架对于扩展的支持都是要相当弹性的。Dubbo作为一个开源框架来说也不可避免。Dubbo采用了简单的扩展方式,基于SPI机制,自定义ExtensionLoader。

什么是SPI

SPI全称为 Service Provider Interface:服务提供者接口,JDK提供了基础的SPI的实现。具体的实现机制为接口编程+策略模式+配置文件组合实现的动态加载机制。

代码

//接口
public interface HelloSPI{

    String sayHello();
}
//接口实现类
public class HelloSPIImpl  implements HelloSPI{
    @Override
    public String sayHello(){
        return "hello SPI";
    }
}

在resource目录下创建 /META-INF/services目录,并且创建以接口文件命名的文件,例如:

  • resource
    • META-INF
      • services
        • com.xx.HelloSPI

并且在com.xx.HelloSPI文件内写入接口实现类,例如:com.xx.HelloSPIImpl

public class Test{


    public void static main(String[]args){

        ServiceLoader<HelloSPI>  serviceLoader = ServiceLoader.load(HelloSPI.class);
        Iterable<HelloSPI> item = serviceLoader.iterator();
        while(item.hasNext()){
            HelloSPI helloSpi = item.next();
            System.out.println(helloSpi.sayHello());
            //print  hello SPI
        }
    }

}

==文件是不是一定要在META-INF目录下创建呢?答案是必须是!在ServiceLoader类中可以看到 PREFIX=“META-INF/services”,所以是从该目录下查找扩展点的!==

通过JDK自带的SPI实现机制可以使程序具有较高的弹性空间!可插拔!而框架只需要提供接口就好了。既然已经具备了扩展性,那么Dubbo为什么还要提供自己的SPI呢?

Dubbo对SPI的改进

  • JDK标准SPI 会一次性实例化扩展点所有时间。如果有扩展实现初始化很耗时,即使没用也加载,这样就很浪费资源
  • 如果扩展点加载失败,连扩展点的名称都拿不到了。
  • 增加对扩展点IOC和AOP的支持,一个扩展点可以直接setter注入其它扩展点
文档更新时间: 2018-12-07 14:32   作者:RuM