Dubbo源码包介绍
当我们从github把Dubbo源码下载下来之后有如下源码包
下面来说明每个包的作用,以便我们有目的的阅读代码
dubbo-admin
dubbo管理平台源码包,用来管理dubbo服务的启动、禁用、降权、接口测试等,操作界面如下
dubbo-cluster
集群模块,将多个服务提供方伪装为一个提供方,包括:负载均衡, 容错,路由等,集群的地址列表可以是静态配置的,也可以是由注册中心下发。
dubbo-common
公共逻辑模块,包括Util类和通用模型
dubbo-config
配置模块,是Dubbo对外的API,用户通过Config使用Dubbo,隐藏Dubbo所有细节
例如:
<bean id=“xxxService” class=“com.xxx.XxxServiceImpl” /> <!-- 和本地服务一样实现远程服务 -->
<dubbo:service interface=“com.xxx.XxxService” ref=“xxxService” /> <!-- 增加暴露远程服务配置 -->
dubbo-container
容器模块,是一个Standlone的容器,以简单的Main加载Spring启动,因为服务通常不需要Tomcat/JBoss等Web容器的特性,没必要用Web容器去加载服务
dubbo-demo
dubbo服务provider和consumer例子
dubbo-filter
dubbo扩展过滤器功能,针对dubbo接口,类似Spring的AOP,经常用的并发控制、超时设置、异常设置、tps限流设置等等都是通过filter来实现的。
dubbo-monitor
监控模块,统计服务调用次数,调用时间的,调用链跟踪的服务
dubbo-registry
注册中心模块,基于注册中心下发地址的集群方式,以及对各种注册中心的抽象。
dubbo-remoting
远程通讯模块,相当于Dubbo协议的实现,如果RPC用RMI协议则不需要使用此包
dubbo-rpc
远程调用模块,抽象各种协议,以及动态代理,只包含一对一的调用,不关心集群的管理
dubbo用到的设计模式
工厂模式
Java SPI
在我们分析工厂模式之前我们先了解下Java SPI(service provice interface)。SPI是JDK内置的一种服务发现机制。目前有不少框架用它来做服务的扩展发现, 简单来说,它就是一种动态替换发现的机制, 举个例子来说, 有个接口,想运行时动态的给它添加实现,你只需要添加一个实现。
而后把新加的实现描述给JDK即可,Dubbo框架就是基于SPI机制提供扩展功能。
我们看下文件目录
各个类的源码如下:
package com.swk.spi;
public interface HelloInterface {
public void sayHello();
}
package com.swk.spi.impl;
import com.swk.spi.HelloInterface;
public class ImageHello implements HelloInterface{
@Override
public void sayHello() {
System.out.println("image hello");
}
}
package com.swk.spi.impl;
import com.swk.spi.HelloInterface;
public class TextHello implements HelloInterface{
@Override
public void sayHello() {
System.out.println("text hello");
}
}
package com.swk.spi;
import java.util.ServiceLoader;
public class SPIMain {
public static void main(String[] args) {
ServiceLoader<HelloInterface> loaders = ServiceLoader.load(HelloInterface.class);
for(HelloInterface in:loaders){
in.sayHello();
}
}
}
com.swk.spi.HelloInterface文件内容如下,添加一个实现类的全名就可以调用这个类里面的方法
com.swk.spi.impl.TextHello
com.swk.spi.impl.ImageHello
运行结果如下
text hello
image hello
下面我们看看dubbo的实现,dubbo的扩展机制和java的SPI机制非常相似,但是又增加了如下功能:
1、可以方便的获取某一个想要的扩展实现,java的SPI机制就没有提供这样的功能
2、对于扩展实现IOC依赖注入功能:
现在实现者A1含有setB()方法,会自动注入一个接口B的实现者,此时注入B1还是B2呢?都不是,而是注入一个动态生成的接口B的实现者B$Adpative,该实现者能够根据参数的不同,自动引用B1或者B2来完成相应的功能
3、对扩展采用装饰器模式进行功能增强,类似AOP实现的功能
private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
我们以Protocal为例来分析下
@SPI("dubbo")
public interface Protocol {
/**
* 获取缺省端口,当用户没有配置端口时使用。
*
*