一。ServiceBean 处理继承 dubbo 自己的配置抽象类以外,还实现了一系列的 spring 接口用来参与到 spring 容器的启动以及 bean 的创建过程中去。由于 spring 的实例化 ServiceBean 是单例模式的,在 Spring 的容器 ApplicationContext 的启动过程 refresh 过程中最后第二步会预先初始化单例的 bean, 在 bean 的初始
化过程会设置 beanName, 设 置 容 器 applicationContext, 回 调InitializingBean 的 afterPropertiesSet最后一步 finishRefresh 会触发 ContextRefreshedEvent 事件, 而 ServiceBean
实现了 ApplicationListener 接口监听了此事件, 而在之前一步实例化的ServiceBean 注 册 了 这 个 事 件 , 所 以 ServiceBean 的onApplicationEvent(ApplicationEvent event)方法被触发, 在这个方法中触发了 export 方法来暴露服务(如下)。
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (isDelay() && !isExported() && !isUnexported()) {
if (logger.isInfoEnabled()) {
logger.info("The service ready on spring started. service: " +
getInterface());
}
export();//调用父类的export方法
}
}
二。ServiceBean继承extends ServiceConfig;
ServiceConfig.export()->ServiceConfig.doExport()->doExportUrls;
ServiceConfig.doExportUrls()执行具体的 export 过程
1. loadRegistries(true)
checkRegistry 如果 xml 中没有配置注册中,从 dubbo.properties 中读取配
置,构建 RegistryConfig 对象并赋值
构建注册中心 URL 统一数据模式集合 List<registryUrl>
2. 因为 dubbo 支持多协议配置,遍历所有协议分别根据不同的协议把服务
export 到不同的注册中心上去
a) 判断是否是泛型暴露
b) 根据协议构建暴露服务的统一数据模型 URL
c) 配置的了 monitor 加载 monitor,并给 URL 设置 MONITOR_KEY
d) 给注册中 regitryUrl 设置 EXPORT_KEY 值为前面构建的暴露服务 urle) 根据服务具体实
现,实现接口以及 registryUrl 从代理工厂 ProxyFactory 获
取代理 Invoker(继承于 AbstractProxyInvoker) ,它是对具体实现的一种代理
f) Protocol.export(invoker) 暴露服务 invoker
Invoker 包含上一步传入的 RegistryUrl, registryUrl的protocol值为registry
ProtocolListenerWrapper 和 ProtocolFilterWrapper 对于协议为
REGISTRY_PROTOCOL 直接跳过,最终由 RegistryProtocol处理export的过程
3.Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass,
registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
DelegateProviderMetaDataInvoker wrapperInvoker = new
DelegateProviderMetaDataInvoker(invoker, this);
Exporter<?> exporter = protocol.export(wrapperInvoker);
三。RegistryProtocol 暴露服务过程,这里传入的Invoker是由RegistryUrl(注册中心url) 从
ProxyFactory 得到的
暴露服务 开启端口:(会调用DubboProtocol端口开启)
1. 从Invoker 获取 providerUrl(生成者url)在获取 cacheKey,根据 cacheKey 获取
本地缓存的 ExporterChangeableWrapper(exporter代理,建立返回的
exporter 与 protocol export出的exporter 的对应关系),如果存在返回。
2. 如果不存在,根据传入的Invoker获取providerUrl, 在构建
InvokerDelegete(originInvoker,providerUrl)
3. Protocol.export(invokerDelegete)根据providerUrl的协议(一般是
dubbo协议)通过Protocol的设配类暴露服务,得到exporter
4. 利用providerUr导出的exporter和invoker构建对象
ExporterChangeableWrapper缓存到本地
获取注册中心
5. 由 Invoker得到registryUrl。
在根据registryUrl从RegistryFactory获取Registry,获取
RegistryUrl 的注册中心协议,这里我们拿 zooKeeper 协议为例。由 dubbo
的扩展机制得到的是ZookeeperRegistryFactory, 得到注册器为ZookeeperRegistry
6. 由 Invoker 获取 ProviderUrl 在去除不需要在注册中心看到的字段得到registryProviderUrl
注册服务url
7. 注册中(ZookeeperRegistry)registryProviderUrlRegistry.register(registryProviderUrl)
8. 由 registryProviderUrl 获取overrideSubscribeUrl,在构建OverrideListener
注册中心绑定订阅 生产者服务
9. registry.subscribe(overrideSubscribeUrl,overrideSubscribeListener) 注册中心订阅这个
url,用来当数据变化通知重新暴露, 以zookeeper为例,暴露服务会在zookeeper 生成一个
节点,当节点发生变化的时候会触发 overrideSubscribeListener的notify 方法重新暴露服务
10.构建并返回一个新的exporter实例
五。DubboProtocol 暴露服务的过程
1. 从invoker获取统一数据模型url
2.由url构建serviceKey(一般由端口,接口名,版本, group 分组)
如: com.alibaba.dubbo.demo.DemoService:20880 这个是由接口和端口组成的
3. 构建 DubboExporter 放入本地 map 做缓存
4. 根据 url openserver。 查找本地缓存以 key 为 url.getAddress 如果没有
ExchangeServer 创建。设置 heartbeat 时间,设置编码解码协议
根据 url 和 ExchangeHandler 绑定 server 并返回(具体如何绑定专题介绍)
5. 返回 DubboExporter 对象