理解Dubbo-SPI机制

Dcr 1年前 ⋅ 807 阅读

说到Dubbo的SPI机制,就不得不先说说SPI机制是什么了.

SPI(Service Provider Interface),大多数开发人员可能不太熟悉,因为这个是针对厂商或者插件的.在java.util.ServiceLoader的文档里面有比较详细的介绍.

简单总结spi机制的思想,系统内部各个模块往往有多种不同的实现方案,面向对象的设计里,一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码.为了实现在模块装配的时候能在不同程序里动态指定,就需要一种服务发现的机制.而spi就是这样的机制.

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

同时jdk提供了服务实现查找的一个工具类:java.util.ServiceLoader

但是Dubbo并没有使用java实现的spi,而是用了自定义的spi.至于为什么不适用java原生的spi实现,就得说说java SPI哪里不好了, javaSPI在查找拓展实现类的时候遍历SPI的配置文件并且将实现类全部实例化,这个过程就产生了资源的浪费.
所以说java spi无法按需加载实现类.

Dubbo SPI
因此Dubbo就自己实现了一个SPI,通过名字取文件里面找到对应的实现类全限定名然后加载实例化即可,并且Dubbo SPI还增加了IOC和AOP的特性,还有自适应拓展机制.

不同于Java SPI, Dubbo分了三类目录:

1.META-INF/services/ 目录:该目录下的 SPI 配置文件是为了用来兼容 Java SPI

2.META-INF/dubbo/ 目录:该目录存放用户自定义的 SPI 配置文件

3.META-INF/dubbo/internal/ 目录:该目录存放 Dubbo 内部使用的 SPI 配置文件

在Duboo的SPI实现里,ExtensionLoader就类似Java SPI里的ServiceLoader.

从ExtensionLoader内部实现中可以看出对于加载过的实例通过ConcurrentMap缓存(同时缓存了class和实例),在加载过程中如果缓存中没有则通过调用反射创建实例.然后通过set方法注入依赖.

 

全部评论: 0

    我有话说: