dubbo源码六:DubboInvoker中的doInvoke方法解析

文章目录

      • 一、RpcInvocation的构造
      • 二、获取信息交换层的ExchangeClient,实例化是ReferenceCountExchangeClient
      • 三、远程调用
        • 1. 获取本次调用是不是异步调用,放到 isAsync 变量中
        • 2. 方法返回类型是否是CompletableFuture类型,放到 isAsyncFuture 变量中
        • 3. 判断方法中有没有返回值,默认值是true,放到 isOneWay 变量中
        • 4. 获取用户配置的超时时间(timeout标签),若没有设置,就使用默认1s,放到 timeout 变量中
        • 5. 发起调用过程

直接Debug到DubboInvoker中的doInvoke方法,如下:
dubbo源码六:DubboInvoker中的doInvoke方法解析_第1张图片

其中debug中的变量如下:
dubbo源码六:DubboInvoker中的doInvoke方法解析_第2张图片

从代码中看,主要分成三个部分:

一、RpcInvocation的构造

       首先把传递进来的 invocation 强制转化为 RpcInvocation 对象,然后设置了分别以“path”和“version”为key的参数,如下:

dubbo源码六:DubboInvoker中的doInvoke方法解析_第3张图片

二、获取信息交换层的ExchangeClient,实例化是ReferenceCountExchangeClient

ReferenceCountExchangeClient会将请求交HeaderExchangeClient处理,不进行任何其他操作。另外HeaderExchangeClient提供心跳检查功能,同时将send、request、close等事件转由HeaderExchangeChannel处理。

三、远程调用

1. 获取本次调用是不是异步调用,放到 isAsync 变量中

  通常来说在配置文件中dubbo设置异常调用有以下两种方式
  • 第一种:若配置里添加,表示单个方法xxx使用异步方式
  • 第二种:若demoService下的所有方法都使用异步,直接配置为
    这里看下获取 isAsync 变量的方法,如下:
    dubbo源码六:DubboInvoker中的doInvoke方法解析_第4张图片
    上面方法中首先判断传递进来的Invocation(已经转化为RpcInvocation)中attachments属性是否包含“async”的key,然后再从方法配置中是否含有async标签(即上面配置方式,默认是false),
    那么Invocation是怎么把async设值进去的呢?回顾一下dubbo的方法调用过程,会直接调用 InvokerInvocationHandler 的 invoke 方法,这里先回到调用方法:
    dubbo源码六:DubboInvoker中的doInvoke方法解析_第5张图片
    dubbo源码六:DubboInvoker中的doInvoke方法解析_第6张图片
    在这里插入图片描述
    首先看方法和它的类中是否同时满足
  • 含有 @AsyncFor 注解
  • 方法名以“Async”结尾
  • 是CompletableFuture类的返回类型

若上面都满足,则构造把异步信息放到RpcInvocation中,若不满足的话,再判断方法返回值的类型是否是CompletableFuture类型,若有,则加入异步信息,否则不做任何处理。

2. 方法返回类型是否是CompletableFuture类型,放到 isAsyncFuture 变量中

判断 RpcInvocation 即inv变量中是参数中是否设置了“future_generated” 和 “future_returntype”的key,通过第1点的分析,两个key设置为true的条件之一是方法返回类型是CompletableFuture类型,所以 isAsyncFuture 变量存放的是调用的方法返回值类型是否 CompletableFuture类型。

3. 判断方法中有没有返回值,默认值是true,放到 isOneWay 变量中

首先从 inv 中参数中获取,然后从url中判断。
dubbo源码六:DubboInvoker中的doInvoke方法解析_第7张图片

4. 获取用户配置的超时时间(timeout标签),若没有设置,就使用默认1s,放到 timeout 变量中

5. 发起调用过程

  • 如果方法不需要返回值,不管同步还是异步,请求直接发出,不会创建Future,直接返回RpcResult空对象
  • 如果方法是isAsync(异步),则
    • 先创建ResponseFuture对象,之后使用FutureAdapter包装该ResponseFuture对象;(创建ResponseFuture对象与同步的代码相同,最后得到的是一个DefaultFuture对象)
    • 然后将该FutureAdapter对象设入当前线程的上下文中RpcContext.getContext();
    • 最后根据有无CompletableFuture类型的返回值来返回不同的Result(有CompletableFuture类型的返回值,则返回AsyncRpcResult,无则返回SimpleAsyncRpcResult对象实例)
  • 如果是同步且有返回值,则先创建ResponseFuture对象,之后直接调用其get()方法进行阻塞调用,直到返回结果后返回。

其中 SimpleAsyncRpcResult 继承于 AsyncRpcResult ,执行构造方法的时候都是调用 AsyncRpcResult 的构造方法,如下:
dubbo源码六:DubboInvoker中的doInvoke方法解析_第8张图片

四、参考
参考dubbo异步调用:https://dubbo.gitbooks.io/dubbo-user-book/content/demos/async-call.html

dubbo源码六:DubboInvoker中的doInvoke方法解析_第9张图片
dubbo源码六:DubboInvoker中的doInvoke方法解析_第10张图片

你可能感兴趣的:(研发管理,dubbo源码分析)