美文网首页
第10章 Dubbo 代理层的设计与实现

第10章 Dubbo 代理层的设计与实现

作者: 原水寒 | 来源:发表于2019-07-24 12:55 被阅读0次
image.png

本节介绍 Dubbo 十层架构中的 Proxy 层。

image.png
  • ProxyFactory:代理工厂接口;
  • StubProxyFactoryWrapper:代理工厂装饰类(封装了对 stublocal 的处理逻辑),会在获取 ProxyFactory 具体子类时进行 AOP;
  • AbstractProxyFactory:代理工厂模板类(封装了获取组装接口的功能,用于创建动态代理),提供了模板方法;
  • JavassistProxyFactory:基于 Javassist 实现的代理工厂;
  • JdkProxyFactory:基于 JDK 动态代理实现的代理工厂;
  • AbstractProxyInvoker:最终封装的代理 Invoker,其子类内部发起真正的调用;
  • InvokerInvocationHandler:Proxy 发起调用时,会调用该类的 invoke(...),在该 invoke(...) 方法中,默认会调用 MockClusterInvoker 的 invoke(...),之后一路进行调用。

一、代理工厂接口 ProxyFactory

@SPI("javassist")
public interface ProxyFactory {
    /**
     * 使用端:consumer
     *
     * 创造一个代理,用于服务引用创建代理
     * @param invoker会被proxy调用的第一层Invoker,默认是 MockClusterInvoker
     * @return proxy 代理对象
     */
    @Adaptive({Constants.PROXY_KEY})
    <T> T getProxy(Invoker<T> invoker) throws RpcException;

    /**
     * 使用端:provider
     *
     * 创建一个Invoker,默认是代理Invoker -- AbstractProxyInvoker 的子类对象
     * @param <T> 接口 eg. com.alibaba.dubbo.demo.DemoService
     * @param proxy ref实例, eg. emoServiceImpl实例
     * @param type interface eg. com.alibaba.dubbo.demo.DemoService
     * @param url -- 
     *       injvm://127.0.0.1/com.alibaba.dubbo.demo.DemoService?anyhost=true...
     *       registry://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider...&export=dubbo://10.213.11.98:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true...
     * @return invoker,默认是代理Invoker -- AbstractProxyInvoker 的子类对象
     */
    @Adaptive({Constants.PROXY_KEY})
    <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException;
}

二、代理工厂装饰类 StubProxyFactoryWrapper

public class StubProxyFactoryWrapper implements ProxyFactory {
    // 真正的ProxyFactory具体子类(JavassistProxyFactory/JdkProxyFactory)
    private final ProxyFactory proxyFactory;
    
    // 具有父类SPI接口(ProxyFactory)的单参构造器,所以该类是一个Wrapper类,会在getExtension获取ProxyFactory具体子类时进行aop
    public StubProxyFactoryWrapper(ProxyFactory proxyFactory) {
        this.proxyFactory = proxyFactory;
    }

    /**
     * 使用端:consumer
     */
    @Override
    public <T> T getProxy(Invoker<T> invoker) throws RpcException {
        // 1. 调用 ProxyFactory 获取代理
        T proxy = proxyFactory.getProxy(invoker);
        // 2. 如果不是泛化接口,处理 stub 和 local
        ...
        return proxy;
    }

    /**
     * 使用端:provider
     */
    @Override
    public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException {
        return proxyFactory.getInvoker(proxy, type, url);
    }
}

三、代理工厂模板类 AbstractProxyFactory

public abstract class AbstractProxyFactory implements ProxyFactory {
    @Override
    public <T> T getProxy(Invoker<T> invoker) throws RpcException {
        /**
         * 1. 构造接口参数,默认只有 invoker.getInterface()(eg. DemoService), EchoService.class 两个接口
         */
        ...
        Class<?>[] interfaces = new Class<?>[]{invoker.getInterface(), EchoService.class};
        ...

        /**
         * 2. 调用子类的实现去创建代理
         */
        return getProxy(invoker, interfaces);
    }

    /**
     * 提供给子类的抽象方法
     */
    public abstract <T> T getProxy(Invoker<T> invoker, Class<?>[] types);

}

四、JdkProxyFactory

public class JdkProxyFactory extends AbstractProxyFactory {
    // 使用端:consumer
    @Override
    public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
        // 使用JDK方式创建Java动态代理,创建了动态代理的逻辑处理类 InvokerInvocationHandler,并且传入了 MockClusterInvoker
        return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new InvokerInvocationHandler(invoker));
    }

    // 使用端:provider
    @Override
    public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
        // 创建真正的Invoker代理
        return new AbstractProxyInvoker<T>(proxy, type, url) {
            @Override
            protected Object doInvoke(T proxy, String methodName,
                                      Class<?>[] parameterTypes,
                                      Object[] arguments) throws Throwable {
                // 获取真正的方法Method,proxy=DemoServiceImpl实例
                Method method = proxy.getClass().getMethod(methodName, parameterTypes);
                // 执行真正的方法
                return method.invoke(proxy, arguments);
            }
        };
    }
}

五、JavassistProxyFactory

public class JavassistProxyFactory extends AbstractProxyFactory {
    // 使用端:consumer
    @Override
    public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
        // 使用 com.alibaba.dubbo.common.bytecode.Proxy 创建代理,创建了动态代理的逻辑处理类 InvokerInvocationHandler,并且传入了 MockClusterInvoker
        return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
    }

    // 使用端:provider
    @Override
    public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
        // wrapper:通过动态生成一个真实的服务提供者(DemoServiceImpl)的wrapper类,来避免反射调用
        final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass());
        return new AbstractProxyInvoker<T>(proxy, type, url) {
            @Override
            protected Object doInvoke(T proxy, String methodName,
                                      Class<?>[] parameterTypes,
                                      Object[] arguments) throws Throwable {
                // 直接调用wrapper,wrapper底层调用DemoServiceImpl
                return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
            }
        };
    }
}

首先来看下 consumer 端:

Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker))

这里首先调用 Proxy.getProxy(interfaces) 获取到一个创建代理的工厂类 com.alibaba.dubbo.common.bytecode.Proxy0,如下:

package com.alibaba.dubbo.common.bytecode;

import com.alibaba.dubbo.common.bytecode.ClassGenerator;
import com.alibaba.dubbo.common.bytecode.Proxy;
import com.alibaba.dubbo.common.bytecode.proxy0;
import java.lang.reflect.InvocationHandler;

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

之后调用了 Proxy0#newInstance 方法,创建了一个 com.alibaba.dubbo.common.bytecode.proxy0 实例,该实例就是最终的 DemoService 的代理对象。

DemoService demoService = (DemoService) context.getBean("demoService");

这里的 demoService 就是上述的 com.alibaba.dubbo.common.bytecode.proxy0 实例。

package com.alibaba.dubbo.common.bytecode;

import com.alibaba.dubbo.common.bytecode.ClassGenerator;
import com.alibaba.dubbo.demo.DemoService;
import com.alibaba.dubbo.rpc.service.EchoService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

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

    public String sayHello(String string) {
        Object[] arrobject = new Object[]{string};
        Object object = this.handler.invoke(this, methods[0], arrobject);
        return (String)object;
    }

    public Object $echo(Object object) {
        Object[] arrobject = new Object[]{object};
        Object object2 = this.handler.invoke(this, methods[1], arrobject);
        return object2;
    }

    public proxy0() {
    }

    public proxy0(InvocationHandler invocationHandler) {
        this.handler = invocationHandler;
    }
}
  • proxy0 实现的接口就是 AbstractProxyFactory 中获取的接口;
  • 当调用 proxy0#sayHello 时,实际上其内部执行的是 InvokerInvocationHandlerr#invoke,来看一下 InvokerInvocationHandler。

六、代理逻辑处理类 InvokerInvocationHandler

public class InvokerInvocationHandler implements InvocationHandler {
    /**
     * 第一个被Proxy调用的Invoker,默认为MockClusterInvoker
     */
    private final Invoker<?> invoker;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        ...
        // 1. 创建请求参数RpcInvocation
        // 2. 执行调用
        // 3. 对调用结果进行重建recreate():若响应有异常,直接抛异常;否则返回响应
        return invoker.invoke(new RpcInvocation(method, args)).recreate();
    }
}

七、Invoker代理 AbstractProxyInvoker

public abstract class AbstractProxyInvoker<T> implements Invoker<T> {
    // 真实对象 ref, eg. DemoServiceImpl
    private final T proxy;
    // 接口类型,eg. DemoService
    private final Class<T> type;
    ...
    public AbstractProxyInvoker(T proxy, Class<T> type, URL url) {
        ...
        this.proxy = proxy;
        this.type = type;
        ...
    }
   ...
    /**
     * 进行调用
     * @param invocation 请求参数
     * @return 返回结果
     * @throws RpcException
     */
    @Override
    public Result invoke(Invocation invocation) throws RpcException {
        try {
            // 1. 调用子类发起请求
            // 2. 包装响应为 RpcResult
            return new RpcResult(doInvoke(proxy, invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments()));
        } catch (InvocationTargetException e) {
            return new RpcResult(e.getTargetException());
        } catch (Throwable e) {
            throw new RpcException("Failed to invoke remote proxy method " + invocation.getMethodName() + " to " + getUrl() + ", cause: " + e.getMessage(), e);
        }
    }

    // 子类覆写的真正调用的方法
    protected abstract Object doInvoke(T proxy, String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Throwable;
}

AbstractProxyInvoker 的子类在 JdkProxyFactory#getInvoker(...)JavassistProxyFactory#getInvoker(...) 中进行创建的,来看下JavassistProxyFactory#getInvoker(...)

    // 使用端:provider
    @Override
    public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
        // wrapper:通过动态生成一个真实的服务提供者(DemoServiceImpl)的wrapper类,来避免反射调用
        final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass());
        return new AbstractProxyInvoker<T>(proxy, type, url) {
            @Override
            protected Object doInvoke(T proxy, String methodName,
                                      Class<?>[] parameterTypes,
                                      Object[] arguments) throws Throwable {
                // 直接调用wrapper,wrapper底层调用DemoServiceImpl
                return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
            }
        };
    }

再贴下最终生成的 wrapper 类实例(com.alibaba.dubbo.common.bytecode.Wrapper0)。

package com.alibaba.dubbo.common.bytecode;

import com.alibaba.dubbo.common.bytecode.ClassGenerator;
import com.alibaba.dubbo.common.bytecode.NoSuchMethodException;
import com.alibaba.dubbo.common.bytecode.NoSuchPropertyException;
import com.alibaba.dubbo.common.bytecode.Wrapper;
import com.alibaba.dubbo.demo.DemoService;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

public class Wrapper0 extends Wrapper implements ClassGenerator.DC {
    ...
    /**
     * @param object 实现类ref,eg. DemoServiceImpl
     * @param string 方法名称
     * @param arrclass 参数类型
     * @param arrobject 参数值
     * @return 调用返回值
     * @throws java.lang.reflect.InvocationTargetException
     */
    public Object invokeMethod(Object object, String string, Class[] arrclass, Object[] arrobject) throws InvocationTargetException {
        DemoService demoService;
        try {
            demoService = (DemoService)object;
        } catch (Throwable throwable) {
            throw new IllegalArgumentException(throwable);
        }
        try {
            if ("sayHello".equals(string) && arrclass.length == 1) {
                return demoService.sayHello((String)arrobject[0]);
            }
        } catch (Throwable throwable) {
            throw new InvocationTargetException(throwable);
        }
        throw new NoSuchMethodException(new StringBuffer().append("Not found method \"").append(string).append("\" in class com.alibaba.dubbo.demo.DemoService.").toString());
    }
    ...
}

相关文章

  • 第10章 Dubbo 代理层的设计与实现

    image.png本节介绍 Dubbo 十层架构中的 Proxy 层。 image.pngProxyFactory...

  • Dubbo网络模型(居然肝了两周才写完,吐血推荐)

    本篇为dubbo高性能剖析的下篇,侧重于剖析dubbo在网络层的源码实现及设计。(上篇传送门dubbo的线程模型[...

  • Dubbo部分知识点总结

    Dubbo部分 Dubbo工作原理dubbo工作原理第一层:service层,接口层,给服务提供者和消费者来实现的...

  • Dubbo的整体架构设计有哪些分层

    Dubbo的整体设计分 10 层: 第一层:service 层,接口层,给服务提供者和消费者来实现的(留给开发人员...

  • Dubbo整体设计

    导读 本文主要分析Dubbo框架整体设计及层次划分,内容主要来源于官网 关键字 :Dubbo整体设计、Dubbo层...

  • Dubbo 工作原理

    Dubbo 工作原理 Dubbo 有10层结构: 第一层:service 层,接口层,给服务提供者和消费者来实现的...

  • dubbo

    dubbo框架设计总共分了10层: 1. 服务接口层(Service):该层是与实际业务逻辑相关,就如上面demo...

  • java代理demo

    需求:使用AOP方式打印日志 用户service层,接口与实现类 1.静态代理 静态代理,使用一个代理类,需要实现...

  • 代理

    来源:java动态代理实现与原理详细分析 代理模式是常用的java设计模式,他的特征是代理类与委托类实现同样的接口...

  • 七、Dubbo框架源码分析:分层架构

    一、Dubbo的分层架构: (1)dubbo工作原理 第一层:service层,接口层,给服务提供者和消费者来实现...

网友评论

      本文标题:第10章 Dubbo 代理层的设计与实现

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