Dubbo作为一个Rpc框架,服务端必须得将自己暴露出去,以便客户端的调用,所以我们来看一下dubbo是如何将服务进行暴露的。
首先我们知道,启动dubbo得进行一些配置,如下图所示的一些dubbo标签(关于spring为什么能识别dubbo标签,可以搜索一下spring的schema机制,这里不做阐述,因为不是重点)
然后我们可以在下图的文件中找到两个命名空间处理器(因为dubbo是由阿里巴巴捐赠给apache),点进apache的文件里面
进去之后可以看到就是将配置文件中的信息解析到bean中存放于ioc,那因为我们要暴露service,所以我们看下ServiceBean
public class DubboNamespaceHandler extends NamespaceHandlerSupport {
static {
Version.checkDuplicate(DubboNamespaceHandler.class);
}
@Override
public void init() {
/**
* 解析配置文件中<dubbo:xxx></dubbo:xxx> 相关的配置,并向容器中注册bean信息
*/
registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
registerBeanDefinitionParser("config-center", new DubboBeanDefinitionParser(ConfigCenterBean.class, true));
registerBeanDefinitionParser("metadata-report", new DubboBeanDefinitionParser(MetadataReportConfig.class, true));
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
registerBeanDefinitionParser("metrics", new DubboBeanDefinitionParser(MetricsConfig.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 AnnotationBeanDefinitionParser());
}
}
在ServiceBean这个类中就可以看到服务暴露的方法,我们一路向里点
/**
* dubbo服务导出入口,
* 当容器初始化完成之后,需要处理一些操作,比如一些数据的加载、初始化缓存、特定任务的注册等等。
* 这个时候我们就可以使用Spring提供的ApplicationListener来进行操作
* @param event
*/
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (!isExported() && !isUnexported()) {
if (logger.isInfoEnabled()) {
logger.info("The service ready on spring started. service: " + getInterface());
}
/**
* 导出服务
*/
export();
}
}
一直看到ServiceConfig中的doExportUrl(),上卖弄这个list就是加载我们配置文件中需要注册到的注册中心
/**
* dubbo服务导出核心
*/
private void doExportUrls() {
//加载配置文件中的所有注册中心配置,并且封装为dubbo内部的URL对象列表
List<URL> registryURLs = loadRegis