26.Dubbo隐式参数传递

2020-09-17  本文已影响0人  山海树

首先需要再消费端的AbstractClusterInvoker类的inoke()方法类,把附加属性键值对放到RpcInvocation的attachments变量中,然后经过网络传递到服务端。
服务端则使用ContextFilter对请求进行拦截,并从RpcInvocation中获取attachments中的键值对,然后使用RpcContext.getContext().setAttachement设置到上下文对象中。

消费端:AbstractClusterInvoker方法

 public Result invoke(final Invocation invocation) throws RpcException {
        checkWhetherDestroyed();

        // binding attachments into invocation.
        Map<String, String> contextAttachments = RpcContext.getContext().getAttachments();
        if (contextAttachments != null && contextAttachments.size() != 0) {
            ((RpcInvocation) invocation).addAttachments(contextAttachments);
        }

        List<Invoker<T>> invokers = list(invocation);
        LoadBalance loadbalance = initLoadBalance(invokers, invocation);
        RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
        return doInvoke(invocation, invokers, loadbalance);
    }

添加的隐式参数最终是要清除的,当发送完成后,将会在ConsumerContextFilter的invoker中清除

  public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        RpcContext.getContext().setInvoker(invoker).setInvocation(invocation).setLocalAddress(NetUtils.getLocalHost(), 0).setRemoteAddress(invoker.getUrl().getHost(), invoker.getUrl().getPort());
        if (invocation instanceof RpcInvocation) {
            ((RpcInvocation)invocation).setInvoker(invoker);
        }

        Result var3;
        try {
            RpcContext.removeServerContext();
            var3 = invoker.invoke(invocation);
        } finally {
            RpcContext.getContext().clearAttachments();
        }

        return var3;
    }

服务端:ContextFilter方法

 public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        Map<String, String> attachments = invocation.getAttachments();
        if (attachments != null) {
            attachments = new HashMap((Map)attachments);
            ((Map)attachments).remove("path");
            ((Map)attachments).remove("interface");
            ((Map)attachments).remove("group");
            ((Map)attachments).remove("version");
            ((Map)attachments).remove("dubbo");
            ((Map)attachments).remove("token");
            ((Map)attachments).remove("timeout");
            ((Map)attachments).remove("async");
            ((Map)attachments).remove("dubbo.tag");
            ((Map)attachments).remove("dubbo.force.tag");
        }

        RpcContext.getContext().setInvoker(invoker).setInvocation(invocation).setLocalAddress(invoker.getUrl().getHost(), invoker.getUrl().getPort());
        if (attachments != null) {
            if (RpcContext.getContext().getAttachments() != null) {
                RpcContext.getContext().getAttachments().putAll((Map)attachments);
            } else {
                RpcContext.getContext().setAttachments((Map)attachments);
            }
        }

        if (invocation instanceof RpcInvocation) {
            ((RpcInvocation)invocation).setInvoker(invoker);
        }

        Result var4;
        try {
            var4 = invoker.invoke(invocation);
        } finally {
            RpcContext.removeContext();
            RpcContext.removeServerContext();
        }

        return var4;
    }

服务端会在此时将接受到的隐式参数设置到上下文中。

消费端拦截器的添加时机


image.png

服务端拦截器添加时机


image.png
上一篇 下一篇

猜你喜欢

热点阅读