spring下dubbo启动时究竟会如何决定Protocol和R
2019-06-30 本文已影响0人
dracula337435
复杂系统中可能出现想给不同dubbo
服务指定不同Protocol
和Registry
的需求,显式逐个指定一定有效。
但是,显式逐个指定的做法过于繁琐。如果利用默认机制,用较少显式配置就实现目标就再好不过了。
此外,举个失误案例,想当然认为,服务会使用被定义在同一个xml
中的Protocol
和Registry
,但实际情况不是这样。
本文尝试从源码一级分析spring
下dubbo
启动时如何选择Protocol
和Registry
。
先给结论
会用整个spring
上下文中的所有Protocol
和Registry
不论是xml
还是@Configuration
,无论是否在一个中
如有特殊配置的话,可能会少用些
代码一级的解释
dubbo的xml配置下,<dubbo:>
命名空间的元素方式会被DubboNamespaceHandler
处理。
具体来说,<dubbo:service>
和<dubbo:reference>
会分别被上述Handler处理成ServiceBean
和ReferenceBean
并注册进上下文中。
在ServiceBean
的public void afterPropertiesSet() throws Exception
方法片段如下:
Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);
if (registryConfigMap != null && registryConfigMap.size() > 0) {
List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
for (RegistryConfig config : registryConfigMap.values()) {
if (config.isDefault() == null || config.isDefault().booleanValue()) {
registryConfigs.add(config);
}
}
if (registryConfigs != null && !registryConfigs.isEmpty()) {
super.setRegistries(registryConfigs);
}
}
这段代码主要做的事如下
- 从
ApplicationContext
中找出所有RegistryConfig
类型的bean - 在这些bean中,找到未设置
default
属性(为null
)或default
属性为true
的,放入一个list
中 - 若上述
list
非null
非空,则将其作为registries
至此可知选择Registry
的两个标准
- 从
ApplicationContext
中找出所有RegistryConfig
- 未设置
default
属性(为null
)或default
属性为true
在这段代码外,还有一个if
判断,如下:
if ((getRegistries() == null || getRegistries().isEmpty())
&& (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().isEmpty())
&& (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().isEmpty())) {
// 省略,前一段代码
}
这段判断的顺序主要为,依次判断ServiceBean
自己,Provider
,Application
中是否没有registries
配置
再回头看ServiceBean
中整个afterPropertiesSet()
方法
public void afterPropertiesSet() throws Exception {
// 略对Provider、Application和Module的配置
if ((getRegistries() == null || getRegistries().isEmpty())
&& (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().isEmpty())
&& (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().isEmpty())) {
Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);
if (registryConfigMap != null && registryConfigMap.size() > 0) {
List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
for (RegistryConfig config : registryConfigMap.values()) {
if (config.isDefault() == null || config.isDefault().booleanValue()) {
registryConfigs.add(config);
}
}
if (registryConfigs != null && !registryConfigs.isEmpty()) {
super.setRegistries(registryConfigs);
}
}
}
// 略对Monitor的配置
if ((getProtocols() == null || getProtocols().isEmpty())
&& (getProvider() == null || getProvider().getProtocols() == null || getProvider().getProtocols().isEmpty())) {
Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
if (protocolConfigMap != null && protocolConfigMap.size() > 0) {
List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>();
for (ProtocolConfig config : protocolConfigMap.values()) {
if (config.isDefault() == null || config.isDefault().booleanValue()) {
protocolConfigs.add(config);
}
}
if (protocolConfigs != null && !protocolConfigs.isEmpty()) {
super.setProtocols(protocolConfigs);
}
}
}
// 略对Path的配置,export
}
其中可见,选择Registry
和Protocol
的逻辑大同小异