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

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 getProxy(Invoker invoker) throws RpcException;

    /**
     * 使用端:provider
     *
     * 创建一个Invoker,默认是代理Invoker -- AbstractProxyInvoker 的子类对象
     * @param  接口 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})
     Invoker getInvoker(T proxy, Class 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 getProxy(Invoker invoker) throws RpcException {
        // 1. 调用 ProxyFactory 获取代理
        T proxy = proxyFactory.getProxy(invoker);
        // 2. 如果不是泛化接口,处理 stub 和 local
        ...
        return proxy;
    }

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

三、代理工厂模板类 AbstractProxyFactory

public abstract class AbstractProxyFactory implements ProxyFactory {
    @Override
    public  T getProxy(Invoker 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 getProxy(Invoker invoker, Class[] types);

}

四、JdkProxyFactory

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

    // 使用端:provider
    @Override
    public  Invoker getInvoker(T proxy, Class type, URL url) {
        // 创建真正的Invoker代理
        return new AbstractProxyInvoker(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 getProxy(Invoker invoker, Class[] interfaces) {
        // 使用 com.alibaba.dubbo.common.bytecode.Proxy 创建代理,创建了动态代理的逻辑处理类 InvokerInvocationHandler,并且传入了 MockClusterInvoker
        return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
    }

    // 使用端:provider
    @Override
    public  Invoker getInvoker(T proxy, Class type, URL url) {
        // wrapper:通过动态生成一个真实的服务提供者(DemoServiceImpl)的wrapper类,来避免反射调用
        final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass());
        return new AbstractProxyInvoker(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 implements Invoker {
    // 真实对象 ref, eg. DemoServiceImpl
    private final T proxy;
    // 接口类型,eg. DemoService
    private final Class type;
    ...
    public AbstractProxyInvoker(T proxy, Class 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  Invoker getInvoker(T proxy, Class type, URL url) {
        // wrapper:通过动态生成一个真实的服务提供者(DemoServiceImpl)的wrapper类,来避免反射调用
        final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass());
        return new AbstractProxyInvoker(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 代理层的设计与实现)