Dubbo 源码学习笔记 —— SPI的机制体现

来源:互联网 发布:千方百计软件下载 编辑:程序博客网 时间:2024/06/05 03:46
dubbo官方文档开发者指南中有这句话:

关于SPI,java相关百度热词集中在什么是SPI,SPI API……
什么是SPI?

java官方文档描述:
service is a well-known set of interfaces and (usually abstract) classes. A service provider is a specific implementation of a service. The classes in a provider typically implement the interfaces and subclass the classes defined in the service itself. Service providers can be installed in an implementation of the Java platform in the form of extensions, that is, jar files placed into any of the usual extension directories. Providers can also be made available by adding them to the application's class path or by some other platform-specific means.
…………
参考:
http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html

API和SPI的区别
网上最多的回答都是基于stackoverflow中的回答铺展
What is the difference between Service Provider Interface (SPI) and Application Programming Interface (API)?
More specifically, for Java libraries, what makes them an API and/or SPI?

the API is the description of classes/interfaces/methods/... that you call and use to achieve a goal
the SPI is the description of classes/interfaces/methods/... that you extend and implement to achieve a goal

Put differently, the API tells you what a specific class/method does for you and the SPI tells you what you must do to conform.
Sometimes SPI and API overlap. For example in JDBC the Driver class is part of the SPI: If you simply want to use JDBC, you don't need to use it directly, but everyone who implements a JDBC driver must implement that class.
The Connection interface on the other hand is both SPI and API: You use it routinely when you use a JDBC driver and it needs to be implemented by the developer of the JDBC driver。
参考:
https://stackoverflow.com/questions/2954372/difference-between-spi-and-api

以上的一堆叽里呱啦无非其实是阐述的就是以下的机制

SPI开发编程机制:
SPI(Service Provider Interface),服务提供者扩展标准的接口,调用者可以通过提供SPI接口的具体实现完成调用者的"定制化"开发工作,不同于API(Application Programe Interface),调用者调用API为了实现某功能,SPI采用模板方法的设计模式,在API设计中定义一个SPI接口,第三方使用此接口时可在META-INF下定义一个以接口全名命名的文件,文件内容为第三方扩展此接口的文件名全称(加载时通过classpath自动加载对应的实现类),这样要求调用者提供具体实现来完整SPI接口提供方的功能。dubbo的开发设计除了在Service层和Config层采用的API方式,其他层面均采用SPI定义接口,采用此方式以Ioc的机制将api接口实现的一些细节交给实际调用者实现,框架变的可扩展而核心部分保持稳定。

示例:
dubbo 注册中心层 dubbo-registry

定义了注册接口RegistryFactory,,dubbo支持zookeeper,redis,multicast注册中心,不同类型的注册中心RegistryFactory通过实现getRegistry方法来初始化一个注册中心链接实体。如下图

四个不同类型的注册中心实现可以看作四个服务厂商,分别看dubbo-registry-redis源码和dubbo-registry-zookeeper源码的实现,对应的工厂类实现方法
redis:

zookeeper:

相对复杂,初始化Registry时调用了AbstractRegistryFactory中的模板方法

如上,两者分别实现了getRegistry(URL url)的方法返回不用的Registry实例
dubbo-registry-api作为dubbo registry层的框架层提供RegisryFactory为上下层返回对应的Registry实例进行上下层的程序流动,而通过SPI的方式提供了各种注册中心的支持,这样保证原框架结构不发生变化的情况下活性的扩展了多种服务注册中心的支持。

另外dubbo的SPI实现是对jdk本身的SPI的改善体现,参考官方文档: