美文网首页Java 杂谈
Dubbo消费端服务代理类

Dubbo消费端服务代理类

作者: jerrik | 来源:发表于2018-07-12 15:44 被阅读0次

引言

我们知道Dubbo消费端引用服务的时候是根据本地接口为我们生成代理类,对消费端而言不需要关心具体的实现,代理类帮我们处理底层通信的问题。

        ReferenceConfig<IUserService> reference = newReferenceConfig<IUserService>(); 
        reference.setApplication(application);
        reference.setRegistry(registry); // 多个注册中心可以用setRegistries()
        reference.setInterface(IUserService.class);
        reference.setVersion("1.0.0");

        //此时的userService只是IUserService的一个代理类
        IUserService userService = reference.get(); 

代理类反编译

public class Proxy0 extends Proxy implements DC {
    public Object newInstance(InvocationHandler var1) {
        return new proxy0(var1);
    }

    public Proxy0() {
    }
}
package com.alibaba.dubbo.common.bytecode;

import com.alibaba.dubbo.common.bytecode.ClassGenerator.DC;
import com.alibaba.dubbo.demo.service.IUserService;
import com.alibaba.dubbo.rpc.service.EchoService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.List;

public class proxy0 implements DC, IUserService, EchoService {
    public static Method[] methods;
    private InvocationHandler handler;

    public List findAllUserList() {
        Object[] var1 = new Object[0];
        Object var2 = this.handler.invoke(this, methods[0], var1);
        return (List)var2;
    }

    public String findPasswd(String var1) {
        Object[] var2 = new Object[]{var1};
        Object var3 = this.handler.invoke(this, methods[1], var2);
        return (String)var3;
    }

    public void updateUserById(Integer var1) {
        Object[] var2 = new Object[]{var1};
        this.handler.invoke(this, methods[2], var2);
    }

    public Object $echo(Object var1) {
        Object[] var2 = new Object[]{var1};
        Object var3 = this.handler.invoke(this, methods[3], var2);
        return (Object)var3;
    }

    public proxy0() {
    }

    public proxy0(InvocationHandler var1) {
        this.handler = var1;
    }
}

从代码中可知,具体的方法都是由handler.invoke()来执行的,而且该代理类实现了IUserService接口.我们来看一下JavassistProxyFactory:

public class JavassistProxyFactory extends AbstractProxyFactory {

    @SuppressWarnings("unchecked")
    public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
        return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
    }

    public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
        // TODO Wrapper类不能正确处理带$的类名
        final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < 0 ? proxy.getClass() : type);
        return new AbstractProxyInvoker<T>(proxy, type, url) {
            @Override
            protected Object doInvoke(T proxy, String methodName, 
                                      Class<?>[] parameterTypes, 
                                      Object[] arguments) throws Throwable {
                return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
            }
        };
    }
}

从代码中可知,newInstance()方法里包装了一个InvokerInvocationHandler()对象。

public class InvokerInvocationHandler implements InvocationHandler {

    private final Invoker<?> invoker;
    
    public InvokerInvocationHandler(Invoker<?> handler){
        this.invoker = handler;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        Class<?>[] parameterTypes = method.getParameterTypes();
        if (method.getDeclaringClass() == Object.class) {
            return method.invoke(invoker, args);
        }
        if ("toString".equals(methodName) && parameterTypes.length == 0) {
            return invoker.toString();
        }
        if ("hashCode".equals(methodName) && parameterTypes.length == 0) {
            return invoker.hashCode();
        }
        if ("equals".equals(methodName) && parameterTypes.length == 1) {
            return invoker.equals(args[0]);
        }
        return invoker.invoke(new RpcInvocation(method, args)).recreate();
    }

}

具体的逻辑最终交给了Invoker来执行。

相关文章

  • Dubbo消费端服务代理类

    引言 我们知道Dubbo消费端引用服务的时候是根据本地接口为我们生成代理类,对消费端而言不需要关心具体的实现,代理...

  • Dubbo服务端

    Dubbo服务端的主要功能就是服务提供端向注册中心注册服务,这样消费端能够从注册中心获取相应的服务。 Dubbo ...

  • dubbo 小结

    dubbo soa,rpc框架 提供服务和消费端模式 简单流程 provider 注册服务到zookeper,消费...

  • 难懂的程序员英语:stub

    在dubbo文档上看到这个单词,很蒙 Proxy 服务代理层:服务接口透明代理,生成服务的客户端 Stub 和服务...

  • 这里有一道Dubbo高频面试题+解析,请注意查收

    一道面试题 让我们开门见山,直面主题:Dubbo 服务里面有个服务端,还有个消费端你知道吧? 服务端和消费端都各有...

  • 这里有一道Dubbo高频面试题+解析,请注意查收!

    一道面试题 让我们开门见山,直面主题:Dubbo 服务里面有个服务端,还有个消费端你知道吧? 服务端和消费端都各有...

  • Dubbo剖析-服务降级

    一、前言 dubbo提供了一些服务降级措施,当服务提供端某一个非关键的服务出错时候,dubbo可以对消费端的调用进...

  • Dubbo之服务调用过程

    Dubbo有关服务调用过程,从官网上的一张图可以看出一个总体的大概image.png 服务消费者在本地创建代理类,...

  • 分布式服务框架Dubbo总结-0x02 dubbo常用配置

    常用功能配置 线程池 详细点这里 并发控制 服务提供端 服务消费端 如果

  • Dubbo服务引用

    1 Dubbo服务引用流程 2 Dubbo引用源码分析 2.1 创建代理 Dubbo会为引用服务创建一个代理对象,...

网友评论

    本文标题:Dubbo消费端服务代理类

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