上一篇我们讲了Dubbo的快速指南,今天就开始我们的源码之旅.这里先给大家介绍一下spi机制.
SPI(JDK)
- SPI的设计目标:
SPI的全名为Service Provider Interface.在面想对象的设计里,模块之间是基于接口编程,模块之间不对实现类进行硬编码.一旦代码涉及具体的实现类,那么久违反了可拔插的原则,如果需要替换一种实现类,就需要修改代码.
为了实现在模块装配的时候,不在模块中写死代码,这就需要一种服务发现机制.java spi就提供了这样的一个机制:为某个接口寻找服务的机制,有点类似于ioc的思想.就是讲装备的控制权移交到代码之外.
- SPI的具体约定:
当服务的提供者(Provider),提供了一个接口的多种实现,那么会在jar包的/META-INF/service目录下,创建该接口的同名文件(全路径名)
该文件中的类容就是这个接口的具体实现类名称. 当外部加载这个模块时,就能通过该jar包下/META-INF/service里的配置文件得到具体的实现类名(全路径名),加载并实例化,完成模块的装配.
如mysql中就使用了spi来加载实现类,完成装配.这里我来写一个小demo方便大家理解:
定义接口:
实现类1:
实现类2:
配置:
加载并获取改接口的所有实现类:
结果如下:
加载成功!
但是Dubbo中没有使用jdk的spi,而是使用自己的spi,原因是:JDK标准的SPI会一次性实例化扩展点的所有实现,如果有扩展的话实现初始化的时候会非常耗时,而且没用上的实现也会加载,会很浪费资源.
而Dubbo增加了对扩展点IOC和AOP的支持,一个扩展点可以直接setter注入其他扩展点.
-
dubbo spi的约定
spi文件存储在/META-INF/dubbo/internal目录下,并且名称为接口的全路径名.
spi文件中的格式定义为:扩展名=具体的实现类全路径名称 如:
这个扩展名的用途就是可以不用加载全部的实现类,而是通过这个扩展名(key)来加载实现类.减少了资源的浪费.
现在基本介绍了spi以及spi的作用,下篇开始阅读源码来介绍dubbo spi的目的,途径和实现路径.