本文介绍在spring中dubbo暴露服务的流程
通常情况下dubbo会和spring结合使用, 这里先介绍spring结合的流程,然后描述dubbo本身的服务暴露过程
spring暴露服务
暴露服务 spring 分为3个阶段
- 解析自定义标签: <dubbo:service interface=“com.aya.service.DemoService” ref=“semoService” />
- bean的初始化操作, 用于确保配置了 application,provider 等属性, 也可以配置在这里暴露服务
- spring容器启动完成事件,ServiceBean监听事件,暴露服务
Injvm协议暴露服务
这里和Dubbo的协议暴露区分开,步骤如下
- 用JavassistProxy生成Invoke, 将spring的demoService传入JavassistProxy
- dubbo在创建InjvmProtocol对象时, 具有包装 Protocol 的类: ListenerExporterWrapper和 ProtocolFilterWrapper,
- ListenerExporterWrapper 在暴露服务后,加入监听器,暴露和卸载的时候会触发事件
- ProtocolFilterWrapper 会对Invoker 加入过滤器。 每个过滤器都有自己的特性,这里不进行详细描述
- 执行InjvmProtocol.export 将 InjvmExporter 加入到 InjvmProtocol.exporterMap 的实例字段中存起来。 InjvmProtocol.exporterMap 用于在RPC调用的时候优先查找是不是本地暴露的服务。
Dubbo协议暴露服务
dubbo 暴露服务的过程
- 由spring触发 ContextRefereshEvent ,ServiceBean 监听事件后执行 export方法
- 将 demoService 对象 传给 JavassistProxy 创建Invoker对象
- 将invoker对象调用 RegistryProtocol.export 由于RegistryProtocol实现了 Protocol 接口, 所以创建的时候会加入 ListenerExporterWrapper和 ProtocolFilterWrapper。 但是这两个包装类对 注册中心类型的做了特殊处理,并不会执行任何操作。
- RegistryProtocol.doLocalExport 执行 DubboProtocol.export ,DubboProtocol 创建时也会加入以上两个包装类,会执行具体的包装内容。
- DubboProtocol.export 创建 DubboExporter 加入到 DubboProtocol.exporterMap 这个实例对象中。 然后调用 openServer 开启netty服务。(只会开启一次)
- 执行 Exchangers.bind(url, requestHandler); 开启服务。 requestHandler 是DubboProtocol的实例对象,用于netty接受到请求的处理。 事实上会用多个wrapper包装这个对象
- HeaderExchanger.bind 方法会执行Transporters.bind,将requestHandler 包装,new DecodeHandler(new HeaderExchangeHandler(requestHandler))), 事实上调用: NettyTransporter.bind
- NettyTransporter.bind 会创建NettyServer, NettyServer 在new这个对象的时候,会执行NettyServer.doOpen, 将 requestHandler 继续包装一层 NettyHandler。 那么执行的时候: NettyHandler->HeaderExchangeHandler->DecodeHandler->DubboProtocol$ExchangeHandler. 这里只需要了解服务暴露的时候会启动netty服务,开启端口就可以了
官方服务暴露文章
http://dubbo.apache.org/zh-cn/docs/source_code_guide/export-service.htm
由于都是贴的代码,没有流程图, 本文补上流程图。 让新手更容易理解暴露流程