dubbo解析-DubboBootstrap初始化

本文基于dubbo 2.7.5版本代码


在本文分析一下DubboBootstrap的initialize方法。

private void initialize() {
	if (!initialized.compareAndSet(false, true)) {
		return;//initialize方法只能初始化一次
	}
	ApplicationModel.iniFrameworkExts();//初始化FrameworkExt实现类,这里会调用Environment的initialize方法
	startConfigCenter();//
	useRegistryAsConfigCenterIfNecessary();//
	startMetadataReport();//
	loadRemoteConfigs();//
	checkGlobalConfigs();//
	initMetadataService();//
	initMetadataServiceExporter();//
	initEventListener();//
	if (logger.isInfoEnabled()) {
		logger.info(NAME + " has been initialized!");
	}
}

ApplicationModel.iniFrameworkExts()

初始化FrameworkExt实现类。
Environment是FrameworkExt实现类。Environment的initialize方法首先从ConfigManager获取默认的配置中心对象ConfigCenterConfig,如果存在ConfigCenterConfig对象,那么将ConfigCenterConfig的externalConfiguration和appExternalConfiguration两个属性值设置到Environment的名字一致的两个属性上。

startConfigCenter

该方法从ConfigManager中获得的所有的ConfigCenterConfig对象。然后访问配置中心的配置,将这些配置保存到Environment对象,最后使用这些配置更新ApplicationConfig、MonitorConfig、ModuleConfig等对象的属性。
配置中心可以有多个,在获取配置的时候,顺次访问每个配置中心,配置保存到本地时后访问的配置中心配置会覆盖之前的配置数据。

useRegistryAsConfigCenterIfNecessary

如果在方法startConfigCenter中,从ConfigManager里面没有找到ConfigCenterConfig对象,那么在本方法里面,会判断注册中心配置对象RegistryConfig的useAsConfigCenter值:
1、如果useAsConfigCenter=null或者true,那么就将注册中心作为配置中心,接下来创建对象ConfigCenterConfig,并将RegistryConfig中的地址、协议、用户名等信息设置到ConfigCenterConfig中,然后将ConfigCenterConfig对象添加到ConfigManager,最后再执行一次startConfigCenter。
2、对于其他的useAsConfigCenter值,dubbo跳过该注册中心RegistryConfig。
useAsConfigCenter默认为null。从上面可以看出,dubbo可以配置多个注册中心和配置中心。

startMetadataReport

该方法主要是创建对象MetadataReport,建立与元数据中心的连接。
MetadataReportConfig是元数据中心,用于存储dubbo的元数据信息,这是后增加一个功能。后面的文章在介绍元数据中心。dubbo可以不配置元数据中心。
ApplicationConfig的metadataType字段用于指定元数据中心的类型,有两个值:remote(远程)和local(本地)。该方法首先检查metadataType,如果类型是remote,那么必须配置MetadataReportConfig。
然后该方法使用SPI加载MetadataReportFactory对象,之后通过MetadataReportFactory对象创建MetadataReport对象,MetadataReport对象在构造方法中建立与元数据中心的连接。dubbo使用MetadataReport访问元数据中心。
元数据中心可以配置多个,但是只会使用其中一个,代码如下,dubbo根据MetadataReportConfig配置的address中的协议匹配对应的MetadataReportFactory实现类。

Collection<MetadataReportConfig> metadataReportConfigs = configManager.getMetadataConfigs();
MetadataReportConfig metadataReportConfig = metadataReportConfigs.iterator().next();
MetadataReportInstance.init(metadataReportConfig.toUrl());//只会使用集合的第一个

loadRemoteConfigs

创建RegistryConfig和ProtocolConfig对象,并设置其属性。
该方法首先从Environment对象的appExternalConfigurationMap和externalConfigurationMap字段中获取所有的ProtocolConfig和RegistryConfig的id值,根据id值创建对应的RegistryConfig和ProtocolConfig对象。之后使用Environment对象设置RegistryConfig和ProtocolConfig对象的各个属性。以RegistryConfig的创建为例,代码如下:

List<RegistryConfig> tmpRegistries = new ArrayList<>();
Set<String> registryIds = configManager.getRegistryIds();//获取所有的id
//遍历id
registryIds.forEach(id -> {
	if (tmpRegistries.stream().noneMatch(reg -> reg.getId().equals(id))) {
		tmpRegistries.add(configManager.getRegistry(id).orElseGet(() -> {//id对应的RegistryConfig不存在,则创建
			RegistryConfig registryConfig = new RegistryConfig();
			registryConfig.setId(id);
			registryConfig.refresh();//使用Environment对象的属性值初始化RegistryConfig对象
			return registryConfig;
		}));
	}
});
//将RegistryConfig添加到ConfigManager对象
configManager.addRegistries(tmpRegistries);

从configManager中获取id值,是搜索字段前缀查找的,RegistryConfig的id对应的前缀是:dubbo.registries.,ProtocolConfig的id对应的前缀是:dubbo.protocols.。

checkGlobalConfigs

检查各个配置对象的各个属性设置的值是否合法,检查内容包括是否有非法字符,长度是否超长。
检查的对象有:ApplicationConfig、ConfigCenterConfig、MetadataReportConfig、MonitorConfig、MetricsConfig、ModuleConfig、SslConfig。

initMetadataService

通过SPI加载WritableMetadataService实现类,实现类的名字是由ApplicationConfig类的metadataType字段指定的。
WritableMetadataService继承了接口MetadataService。WritableMetadataService后续文章再分析。

initMetadataServiceExporter

initMetadataServiceExporter创建ConfigurableMetadataServiceExporter对象,initMetadataService方法加载的WritableMetadataService对象作为其属性。ConfigurableMetadataServiceExporter的作用是将WritableMetadataService对象以dubbo服务的形式对外提供服务,这样客户端便可以使用dubbo协议访问MetadataService接口里面的方法。
initMetadataServiceExporter仅仅是创建ConfigurableMetadataServiceExporter对象,对外发布服务是在DubboBootstrap的start方法里面完成的。

initEventListener

本方法是初始化的最后一个方法。该方法是将DubboBootstrap对象注册为监听器。
dubbo有自己实现的事件发布机制,其接口是EventDispatcher,默认实现是DirectEventDispatcher。事件发布机制其他文章介绍。
DubboBootstrap监听所有dubbo的org.apache.dubbo.event.Event事件。

这里可能大家会有一个疑问,对于服务端来说,调用initialize方法是在容器事件发布后,此时各个配置对象都已经创建完毕,在initialize中使用没有什么问题,但是客户端调用该方法的时候,是在对ReferenceBean对象执行bean后处理器,换句话说spring此时还在对ReferenceBean对象创建的过程中,那么dubbo如何保证客户端启动的时候initialize中需要的配置对象都创建完毕了呢?大家可以看《dubbo解析-客户端启动入口》里面提到一个方法doGetInjectedBean,该方法创建ReferenceBean对象,但创建其实委托给ReferenceBeanBuilder,在new ReferenceBean()后,会执行ReferenceBeanBuilder的方法prepareDubboConfigBeans,该方法代码如下:

private void prepareDubboConfigBeans() {
        beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class);
        beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class);
        beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class);
        beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class);
        beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class);
        beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.class);
        beansOfTypeIncludingAncestors(applicationContext, ConsumerConfig.class);
        beansOfTypeIncludingAncestors(applicationContext, ConfigCenterBean.class);
        beansOfTypeIncludingAncestors(applicationContext, MetadataReportConfig.class);
        beansOfTypeIncludingAncestors(applicationContext, MetricsConfig.class);
        beansOfTypeIncludingAncestors(applicationContext, SslConfig.class);
    }

beansOfTypeIncludingAncestors方法获取spring容器中第二个入参要求类型的所有bean对象。dubbo就是通过这个方法保证了在调用DubboBootstrap.initialize方法之前,所有的配置对象都已经创建完毕。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值