关于源码和原理的分析,我们都需要找寻一个切入点,找到切入点的前提是你要知道注册中心的功能是什么,注册中心相信大家都不陌生,每一个通用的注册中心都需要提供两个基本的功能点:
首先我们要确定Dubbo关于注册中心的源码包的位置:org.apache.dubbo.registry。下面我们看一下包的目录结构图:
上图红色框中的9个包对应Dubbo中9种注册中心的实现,从包的名称也可以看出具体的注册中心实现的方式。其中Dubbo官网推荐的注册中心方式的实现是基于ZooKeeper的注册中心。那么下面我们就分析以ZooKeeper为基础的注册中心在Dubbo中是如何实现的。
其实在我们在学习开源框架的过程中,除了学会他们的使用以外,还可以通过分析源码学习这些开源框架的设计,每一个开源框架的实现基本都是易扩展的,这种易扩展的特性都得益于优秀的设计模式。下面我们就先看一下Dubbo在注册中心实现上是怎样设计来支持各种各样的注册中心的。
SPI(Service Provider Interface)是Java提供的一种服务发现的机制。SPI通俗一点讲就是在运行期间使用一个具体的接口实现类来动态的替换接口。
Java中的具体实现很简单,只需要你定义一个接口,然后采用具体的实现类实现这个接口,然后在META-INFO/services建立一个以接口的全量限定名称命名的文件,该文件的内容是具体的接口实现类的全量限定名称。
Java中有一个java.util.ServiceLoader可以查找服务的具体实现。
Dubbo并没有直接使用Java原生的SPI,而是重新实现了一套功能更强的SPI机制。Dubbo SPI的相关逻辑被封装在ExtensionLoader类中,具体分析请见官网。这里只简单讲解一下扩展类动态替换的基本流程。
Dubbo首先会通过反射获取到所有的setter方法,然后通过ExtensionFactory获取到依赖对象,最后通过反射调用将依赖设置到目标对象中。在ExtensionLoader使用的ExtensionFactory是AdaptiveExtensionFactory,AdaptiveExtensionFactory内部维护了一个ExtensionFactory列表,用于存储其他类型的ExtensionFactory。Dubbo目前提供了两种ExtensionFactory,分别是SpiExtensionFactory和SpringExtensionFactory。前者用于创建自适应的拓展,后者是用于从Spring的IOC容器中获取所需的拓展。