接触过dubbo的同学,见到下面的配置都非常熟悉了,含义不多说。
本章主要目的,对DUBBO配置原理进行剖析。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<
beans
xmlns
=
"http://www.springframework.org/schema/beans"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo
=
"http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<!-- 当前应用信息配置 -->
<
dubbo:application
name
=
"demo-provider"
/>
<!-- 连接注册中心配置 -->
<
dubbo:registry
address
=
"N/A"
/>
<!-- 暴露服务协议配置 -->
<
dubbo:protocol
name
=
"dubbo"
port
=
"20813"
/>
<!-- 暴露服务配置 -->
<
dubbo:service
interface
=
"com.alibaba.dubbo.config.spring.api.DemoService"
ref
=
"demoService"
/>
<
bean
id
=
"demoService"
class
=
"com.alibaba.dubbo.config.spring.impl.DemoServiceImpl"
/>
</
beans
>
|
spring加载xml或annotation,第一步需要将这些配置元数据载入spring容器中,首先确认下这些<dubbo:*>标签,对应的数据载体类。
1. 认识标签对应的数据载体
首先,找到dubbo-config\dubbo-config-spring\src\main\resources\META-INF\spring.handlers文件。找到负责具体解析dubbo标签的handler。
1
|
http\://code.alibabatech.com/
schema
/dubbo=com.alibaba.dubbo.config.spring.
schema
.DubboNamespaceHandler
|
查看DubboNamespaceHandler 代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public
class
DubboNamespaceHandler
extends
NamespaceHandlerSupport {
static
{
Version.checkDuplicate(DubboNamespaceHandler.
class
);
}
public
void
init() {
registerBeanDefinitionParser(
"application"
,
new
DubboBeanDefinitionParser(ApplicationConfig.
class
,
true
));
registerBeanDefinitionParser(
"module"
,
new
DubboBeanDefinitionParser(ModuleConfig.
class
,
true
));
registerBeanDefinitionParser(
"registry"
,
new
DubboBeanDefinitionParser(RegistryConfig.
class
,
true
));
registerBeanDefinitionParser(
"monitor"
,
new
DubboBeanDefinitionParser(MonitorConfig.
class
,
true
));
registerBeanDefinitionParser(
"provider"
,
new
DubboBeanDefinitionParser(ProviderConfig.
class
,
true
));
registerBeanDefinitionParser(
"consumer"
,
new
DubboBeanDefinitionParser(ConsumerConfig.
class
,
true
));
registerBeanDefinitionParser(
"protocol"
,
new
DubboBeanDefinitionParser(ProtocolConfig.
class
,
true
));
registerBeanDefinitionParser(
"service"
,
new
DubboBeanDefinitionParser(ServiceBean.
class
,
true
));
registerBeanDefinitionParser(
"reference"
,
new
DubboBeanDefinitionParser(ReferenceBean.
class
,
false
));
registerBeanDefinitionParser(
"annotation"
,
new
DubboBeanDefinitionParser(AnnotationBean.
class
,
true
));
}
}
|
不再进行分析具体代码了。这部分内容和spring的范畴。
1.1对应表格
标签 |
数据配置类 |
含义 |
<dubbo:application name="demo-provider" /> |
ApplicationConfig |
应用级别 |
<dubbo:registry address="N/A" /> |
RegistryConfig |
注册中心 |
<dubbo:protocol name="dubbo" port="20813" /> |
ProtocolConfig | 协议 |
<dubbo:service interface=".." ref="demoService" /> |
ServiceBean |
服务 |
module |
ModuleConfig |
模块 |
monitor | MonitorConfig |
监控 |
consumer | ConsumerConfig | 消费者 |
provider |
ProviderConfig | 提供者 |
reference |
ReferenceBean | 服务引用 |
1.2 Config层次结构
现在,应该很容易找出声明服务的配置入口是哪一个配置类:ServiceBean。其他的类,可以暂时靠边站。其他的配置信息(如ApplicationConfig,RegistryConfig..)主要涉及配置元数据,会决定dubbo运行时行为,但对梳理剖析DUBBO流程不太重要。
2.认识ServiceBean
ServiceBean是声明暴露Service的一个重要组件,需要重点关注。
2.1结构树
还是要感谢spring提供的优秀扩展特性,ServiceBean实现了很多spring的扩展接口。现在,把重点放在AbstractConfig继承树这个层次上。
AbstractConfig提供基础支持方法,比如appendAttributes,check*系列方法等。
AbstractMethodConfig,封装了一些方法级别的相关属性
AbstractInterfaceConfig:封装了接口契约需要的属性
AbstractServiceConfig: 服务相关属性(重在使用运维级别)
ServiceConfig:主要包含一些运行时数据
AbstractMethodConfig 属性片段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public
abstract
class
AbstractMethodConfig
extends
AbstractConfig {
// 远程调用超时时间(毫秒)
protected
Integer timeout;
// 重试次数
protected
Integer retries;
// 最大并发调用
protected
Integer actives;
// 负载均衡
protected
String loadbalance;
// 是否异步
protected
Boolean async;
// 异步发送是否等待发送成功
protected
Boolean sent;
// 服务接口的失败mock实现类名
protected
String mock;
// 合并器
protected
String merger;
// 服务接口的失败mock实现类名
protected
String cache;
// 服务接口的失败mock实现类名
protected
String validation;
..
}
|
AbstractInterfaceConfig.java属性片段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
public
abstract
class
AbstractInterfaceConfig
extends
AbstractMethodConfig {
private
static
final
long
serialVersionUID = -1559314110797223229L;
// 服务接口的本地实现类名
protected
String local;
// 服务接口的本地实现类名
protected
String stub;
// 服务监控
protected
MonitorConfig monitor;
// 代理类型
protected
String proxy;
// 集群方式
protected
String cluster;
// 过滤器
protected
String filter;
// 监听器
protected
String listener;
// 负责人
protected
String owner;
// 连接数限制,0表示共享连接,否则为该服务独享连接数
protected
Integer connections;
// 连接数限制
protected
String layer;
// 应用信息
protected
ApplicationConfig application;
// 模块信息
protected
ModuleConfig module;
// 注册中心
protected
List<RegistryConfig> registries;
// callback实例个数限制
private
Integer callbacks;
// 连接事件
protected
String onconnect;
// 断开事件
protected
String ondisconnect;
// 服务暴露或引用的scope,如果为local,则表示只在当前JVM内查找.
private
String scope;
...
}
|
AbstractServiceConfig 属性片段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
public
abstract
class
AbstractServiceConfig
extends
AbstractInterfaceConfig {
private
static
final
long
serialVersionUID = 1L;
// 服务版本
protected
String version;
// 服务分组
protected
String group;
// 服务是否已经deprecated
protected
Boolean deprecated;
// 延迟暴露
protected
Integer delay;
// 是否暴露
protected
Boolean export;
// 权重
protected
Integer weight;
// 应用文档
protected
String document;
// 在注册中心上注册成动态的还是静态的服务
protected
Boolean dynamic;
// 是否使用令牌
protected
String token;
// 访问日志
protected
String accesslog;
// 允许执行请求数
private
Integer executes;
protected
List<ProtocolConfig> protocols;
// 是否注册
private
Boolean register;
...
}
|
ServiceConfig.java属性片段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
public
class
ServiceConfig<T>
extends
AbstractServiceConfig {
private
static
final
long
serialVersionUID = 3033787999037024738L;
private
static
final
Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.
class
).getAdaptiveExtension();
private
static
final
ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.
class
).getAdaptiveExtension();
private
static
final
Map<String, Integer> RANDOM_PORT_MAP =
new
HashMap<String, Integer>();
// 接口类型
private
String interfaceName;
private
Class<?> interfaceClass;
// 接口实现类引用
private
T ref;
// 服务名称
private
String path;
// 方法配置
private
List<MethodConfig> methods;
private
ProviderConfig provider;
private
final
List<URL> urls =
new
ArrayList<URL>();
private
final
List<Exporter<?>> exporters =
new
ArrayList<Exporter<?>>();
private
transient
volatile
boolean
exported;
private
transient
volatile
boolean
unexported;
private
transient
volatile
boolean
generic;
...
}
|
注意ServiceConfig 有几个很服务声明有关的属性
1
2
3
4
5
|
private
final
List<Exporter<?>> exporters =
new
ArrayList<Exporter<?>>();
private
transient
volatile
boolean
exported;
private
transient
volatile
boolean
unexported;
|
这是剖析服务声明的入口。
本文转自 randy_shandong 51CTO博客,原文链接:http://blog.51cto.com/dba10g/1883784,如需转载请自行联系原作者