美文网首页
26.Dubbo隐式参数传递

26.Dubbo隐式参数传递

作者: 山海树 | 来源:发表于2020-09-17 07:31 被阅读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

    相关文章

      网友评论

          本文标题:26.Dubbo隐式参数传递

          本文链接:https://www.haomeiwen.com/subject/lhrpektx.html