Dubbo原理和源码解析之“微内核+插件“”机制

github新增仓库 "dubbo-read"(点此查看,集合所有《Dubbo原理和源码解析》系列文章,后续将继续补充该系列,同时将针对Dubbo所做的功能扩展也进行分享。不定期更新,欢迎Follow。

  1 框架设计

在官方《Dubbo 开发指南》框架设计部分提到,Dubbo 服务框架的基本设计原则是:

采用 URL 作为配置信息的统一格式,所有扩展点都通过传递 URL 携带配置信息;

采用 Microkernel + Plugin 模式,Microkernel 只负责组装 Plugin,Dubbo 自身的功能也是通过扩展点实现的,也就是 Dubbo 的所有功能点都可被用户自定义扩展所替换;

对于第一点比较容易理解,所有的参数都封装成 Dubbo 自定义的 URL 对象进行传递。URL 对象主要包括以下属性:

String protocol

String host

int port

String path

Map<String, String> parameters

本文将重点介绍第二点,对 Microkernel + Plugin 机制的实现原理、源码进行分析和跟踪。

 

2 API 和 SPI

框架或组件通常有两类客户,一个是使用者,一个是扩展者。API (Application Programming Interface) 是给使用者用的,而 SPI (Service Provide Interface) 是给扩展者用的。
我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块的方案、jdbc模块的方案等。面向的对象的设计里,我们一般推荐 模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了 可拔插的原则,如果需要替换一种实现,就需要修改代码。
为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。JAVA SPI 就提供了这样的一个机制——为某个接口寻找服务实现的机制。有点类似 IOC 的思想,将装配的控制权移到程序之外,在 模块化设计 中这个机制尤其重要。

 

3 JAVA SPI

JAVA SPI 实际上是 ”基于接口编程+策略模式+配置文件“ 组合实现的动态加载机制。具体步骤为:

定义一个接口;

编写接口的一个或多个实现;

src/main/resources/ 下建立 /META-INF/services 目录, 新增一个以接口命名的文件,内容是实现类类名;

使用 ServiceLoader 来加载配置文件中指定的实现。

假设我们提供了一个“打招呼”的接口,有中文版和英文版两种实现:

3.1 定义接口

package com.spi.service; public interface HelloService { public String sayHello(); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwjzxs.html