dubbo系列之服务发布-流程
先上两张经典图,大致了解一下发布流程

源码构成
dubbo-demo-provider.xml——注册文件
1  | <!-- 提供方应用信息,用于计算依赖关系 -->  | 
可以看到服务是通过dubbo的schema service进行注入的,那我们找到DubboNameSpaceHandler文件,即dubbo的命名空间处理器,找到dubbo:service标签解析行。
DubboNameSpaceHandler()
1  | public class DubboNamespaceHandler extends NamespaceHandlerSupport {  | 
ServiceBean类
ServiceBean类可以看到实现了ApplicationListener,这个接口就是spring的时间机制,看看ServiceBean继承这个接口实现的方法。
1  | public void onApplicationEvent(ApplicationEvent event) {  | 
export()
–>ServiceConfig.export()
-->doExport()
  -->doExportUrls()
1  | private void doExportUrls() {  | 
doExportUrlsFor1Protocol()
1  | private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {  | 
暴露本地服务和暴露远程服务的区别是什么?
1.暴露本地服务:指暴露在用一个JVM里面,不用通过调用zk来进行远程通信。例如:在同一个服务,自己调用自己的接口,就没必要进行网络IP连接来通信。
2.暴露远程服务:指暴露给远程客户端的IP和端口号,通过网络来实现通信。
本地暴露
exportLocal(url)
1  | 
  | 
1  | Exporter<?> exporter = protocol.export(  | 
这句话是本地暴露的关键,看官方给的服务提供者暴露一个服务的详细过程,其实也就是这句代码

为了方便理解,介绍一下一些类和方法的概念:
proxyFactory
proxyFactory:就是为了获取一个接口的代理类,例如获取一个远程接口的代理。
它有2个方法,代表2个作用
  a.getInvoker:针对server端,将服务对象,如DemoServiceImpl包装成一个Invoker对象。
  b.getProxy  :针对client端,创建接口的代理对象,例如DemoService的接口。
Wrapper
它类似spring的BeanWrapper,它就是包装了一个接口或一个类,可以通过wrapper对实例对象进行赋值 取值以及指定方法的调用。
Invoker
它是一个可执行的对象,能够根据方法的名称、参数得到相应的执行结果。
1  | 它里面有一个很重要的方法 Result invoke(Invocation invocation);  | 
Invocation
包含了需要执行的方法和参数等重要信息,目前它只有2个实现类RpcInvocation MockInvocation
 它有3种类型的Invoker
1.本地执行类的Invoker
1  | server端:要执行 demoService.sayHello,就通过InjvmExporter来进行反射执行demoService.sayHello就可以了。  | 
2.远程通信类的Invoker
    client端:要执行 demoService.sayHello,它封装了DubboInvoker进行远程通信,发送要执行的接口给server端。
    server端:采用了AbstractProxyInvoker执行了DemoServiceImpl.sayHello,然后将执行结果返回发送给client.
3.多个远程通信执行类的Invoker聚合成集群版的Invoker
    client端:要执行 demoService.sayHello,就要通过AbstractClusterInvoker来进行负载均衡,DubboInvoker进行远程通信,发送要执行的接口给server端。
    server端:采用了AbstractProxyInvoker执行了DemoServiceImpl.sayHello,然后将执行结果返回发送给client.
Protocol
  1.export:暴露远程服务(用于服务端),就是将proxyFactory.getInvoker创建的代理类 invoker对象,通过协议暴露给外部。
  2.refer:引用远程服务(用于客户端), 通过proxyFactory.getProxy来创建远程的动态代理类,例如DemoService的远程动态接口。
exporter
维护invoder的生命周期。
exchanger
信息交换层,封装请求响应模式,同步转异步。
介绍完上面一些概念,接着看看本地暴露接下来的步骤,用一张清晰的图表示。

最终本地暴露的目的就是
1  | exporterMap.put(key, this)//key=com.alibaba.dubbo.demo.DemoService, this=InjvmExporter  | 
远程暴露
doExportUrlsFor1Protocol()
1  | //原理和本地暴露一样都是为了获取一个Invoker对象  | 
远程暴露的关键就是invoker转换导exporter的过程
1  | -->proxyFactory.getInvoker//原理和本地暴露一样都是为了获取一个Invoker对象  | 
———1.netty服务暴露的开始——- –>DubboProtocol.export
1  | -->serviceKey(url)//组装key=com.alibaba.dubbo.demo.DemoService:20880  | 
——–2.信息交换层 exchanger 开始————–>Exchangers.bind(url, requestHandler)//exchaanger是一个信息交换层
1  | -->getExchanger(url)  | 
———3.网络传输层 transporter———————>Transporters.bind
1  | -->getTransporter()  | 
———4.打开断开,暴露netty服务——————————–>doOpen()
1  | -->设置 NioServerSocketChannelFactory boss worker的线程池 线程个数为3  | 
还是贴一张图,理解更清晰一点

DubboProtocol()
1  | public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {  | 
参考链接