0
点赞
收藏
分享

微信扫一扫

dubbo源码-隐式传参

安七月读书 2022-02-19 阅读 69

在业务系统中,如果要使用dubbo的隐式传参功能,可以使用RpcContext对象

使用

在服务消费者这一端这样设置即可

RpcContext.getContext().setAttachment("age","22");

然后在服务提供者这一端

String age = RpcContext.getContext().getAttachment("age");
System.out.println("隐式传参获取到的age:" + age);

就可以获取到设置的参数

源码分析

其实要实现隐式传输的传递,也是需要进行一层转换的
隐式传参的原理,用一句话来解释:
在服务发送的时候(也就是服务消费端),会将设置的参数,在发送请求的时候,一起发送出去
在服务提供者这一端,接收到消费端请求的时候,再将参数取出来

AbstractInvoker

@Override
public Result invoke(Invocation inv) throws RpcException {
    // if invoker is destroyed due to address refresh from registry, let's allow the current invoke to proceed
    if (destroyed.get()) {
        logger.warn("Invoker for service " + this + " on consumer " + NetUtils.getLocalHost() + " is destroyed, "
                + ", dubbo version is " + Version.getVersion() + ", this invoker should not be used any longer");
    }

    RpcInvocation invocation = (RpcInvocation) inv;
    invocation.setInvoker(this);
    if (attachment != null && attachment.size() > 0) {
        invocation.addAttachmentsIfAbsent(attachment);
    }
    // 获取rpcContext中的参数,将隐式传递的参数,放到invocation对象中
    Map<String, String> contextAttachments = RpcContext.getContext().getAttachments();
    if (contextAttachments != null && contextAttachments.size() != 0) {
        invocation.addAttachments(contextAttachments);
    }
    if (getUrl().getMethodParameter(invocation.getMethodName(), Constants.ASYNC_KEY, false)) {
        invocation.setAttachment(Constants.ASYNC_KEY, Boolean.TRUE.toString());
    }
}

invoke方法,会在服务消费者发起调用的时候,被调用到,上面的代码中,我只截取了一部分源码
可以看到,其中一段代码,就是将rpcContext中的隐式参数,取出来,放在invocation对象中,所以,这里就是服务调用者,将RpcContext转换的地方

ContextFilter

这个filter,就是服务提供者,解析invocation中隐式参数的代码

Map<String, String> attachments = invocation.getAttachments();

if (attachments != null) {
    if (RpcContext.getContext().getAttachments() != null) {
        RpcContext.getContext().getAttachments().putAll(attachments);
    } else {
        RpcContext.getContext().setAttachments(attachments);
    }
}

这里我也是只截取了一部分代码,可以看到,先从invocation对象中获取到所有的参数,然后放到了服务提供者这一段的RpcContext对象中
那为什么这个filter,会在服务提供者执行的时候,被调用呢?

@Activate(group = Constants.PROVIDER, order = -10000)

因为这个注解,就表示了只在provider这一侧生效

总结

对于隐式传参来说,并不是直接把RpcContext对象传递过去,而是中间进行了一层转换
RpcContext(消费者) --> Invocation --> RpcContext(服务端)

举报

相关推荐

0 条评论