服务暴露触发
关于服务暴露是怎么被触发的在之前的博客 dubbo与spring 中有简单介绍过。
大体步骤如下:
- 在xml中进行服务配置。
- 根据spring的schema扩展注册的
DubboBeanDefinitionParser,将dubbo相关配置解析成对应的 BeanDefinition。 - BeanDefinition 转换为具体的 Bean 是在spring容器完成
refresh()的过程中
3.1 设置delay且不为-1。ServiceBean实现了InitializingBean,在钩子方法afterPropertiesSet()中触发 export,也就是 bean 在实例化后且在调用<init-method>之前调用。
3.2 未设置delay或值为-1 。ServiceBean实现了ApplicationListener可以监听spring的相关的事件,在spring容器refresh()完后,在onApplicationEvent()完成事件的处理,进而触发 export。
服务暴露过程

服务暴露的过程中比较重要的是在ServiceConfig.doExportUrlFor1Protocol()方法内,会生成具体服务对应的Provider URL后,同时如果存在注册中心还会在URL上加上registry,通过dubbo扩展机制获取ProxyFactory的实现来得到Invoker,然后调用Protocol进行服务暴露。
dubbo中
ProxyFactory扩展实现类有 Javassist 和 JDK 两种方式,默认使用 Javassist 是因为通过字节码操作生成相应的 wrapper类(第一次使用后会将实例化对象缓存起来),避免了每次调用使用Java反射导致的性能低下问题。
|
|
Invoker导出为Exporter分为两种情况:一种是registry协议类型,另一种是其他类型。
这里值的注意的是protocol实际上是自适应类Protocol$Adaptive,因而在运行时是根据URL来动态指定扩展点的实现类,在服务暴露过程中由于URL加上了registry,所以 Protocol 实现类是RegistryProtocol。
同时,Protocol$Adaptive在通过ExtensionLoader.getExtension()获取具体实现类时,会加上一些装饰类的功能(eg: ProtocolFilterWrapper和ProtocolListenerWrapper),这两种装饰类只会对非RegistryProtocol起作用。
当RegistryProtocol进行服务暴露的过程中,会首先调用doLocalExport(),通过默认的DubboProtocol.export()对 Provider URL 进行服务暴露。然后再根据具体的 Registry 进行服务注册和监听器注册,并订阅override数据。
等到真正的DubboProtocol进行服务暴露时,会启动一个服务监听server,通过调用Exchanger和Transporter层的扩展实现完成的。