美文网首页
SOFA RPC客户端源码解析之客户端生成代理类

SOFA RPC客户端源码解析之客户端生成代理类

作者: zy19880406 | 来源:发表于2019-07-12 16:17 被阅读0次
    1. 时序
    clientStuGenSeq.png

    说明:

    ​ 1.创建Cluser并初始化,创建proxyInstance代理

    try {
        // build cluster
        cluster = ClusterFactory.getCluster(this);
        // build listeners
        consumerConfig.setConfigListener(buildConfigListener(this));
        consumerConfig.setProviderInfoListener(buildProviderInfoListener(this));
        // init cluster
        cluster.init();
        // 构造Invoker对象(执行链)
        proxyInvoker = buildClientProxyInvoker(this);
        // 创建代理类
        proxyIns = (T) ProxyFactory.buildProxy(consumerConfig.getProxy(), consumerConfig.getProxyClass(),
            proxyInvoker);
    } catch (Exception e) {
        ...
    }
    

    2.创建代理类,这里使用SPI扩展机制找到Proxy,默认提供jdk及javassist实现,根据传入proxyType找到对应的Proxy创建代理对象,默认proxyType是javassist

       /**
         * 构建代理类实例
         *
         * @param proxyType    代理类型
         * @param clazz        原始类
         * @param proxyInvoker 代码执行的Invoker
         * @param <T>          类型
         * @return 代理类实例
         * @throws Exception
         */
        public static <T> T buildProxy(String proxyType, Class<T> clazz, Invoker proxyInvoker) throws Exception {
            try {
                ExtensionClass<Proxy> ext = ExtensionLoaderFactory.getExtensionLoader(Proxy.class)
                    .getExtensionClass(proxyType);
                if (ext == null) {
                    throw ExceptionUtils.buildRuntime("consumer.proxy", proxyType,
                        "Unsupported proxy of client!");
                }
                //获取代理类
                Proxy proxy = ext.getExtInstance();
                //生成代理对象
                return proxy.getProxy(clazz, proxyInvoker);
            } catch (SofaRpcRuntimeException e) {
                throw e;
            } catch (Throwable e) {
                throw new SofaRpcRuntimeException(e.getMessage(), e);
            }
        }
    

    3.使用javassist动态生成代理类,并传入代理对象invokerProxy用于与服务端通信,JavassistProxy代理类生成的类的方法如下(参考JDKInvocationHandler实现)

    String methodName = method.getName();
    Class[] paramTypes = method.getParameterTypes();
    if ("toString".equals(methodName) && paramTypes.length == 0) {
        return proxyInvoker.toString();
    } else if ("hashCode".equals(methodName) && paramTypes.length == 0) {
        return proxyInvoker.hashCode();
    } else if ("equals".equals(methodName) && paramTypes.length == 1) {
        Object another = paramValues[0];
        return proxy == another ||
            (proxy.getClass().isInstance(another) && proxyInvoker.equals(JDKProxy.parseInvoker(another)));
    }
    SofaRequest sofaRequest = MessageBuilder.buildSofaRequest(method.getDeclaringClass(),
        method, paramTypes, paramValues);
        //真正与服务端通信的对象,当然这里面还有负载均衡器,过滤器链等。。(待续)最终使用netty与服务端通信
    SofaResponse response = proxyInvoker.invoke(sofaRequest);
    if (response.isError()) {
        throw new SofaRpcException(RpcErrorType.SERVER_UNDECLARED_ERROR, response.getErrorMsg());
    }
    //返回服务端对象
    Object ret = response.getAppResponse();
    if (ret instanceof Throwable) {
        throw (Throwable) ret;
    } else {
        if (ret == null) {
            return ClassUtils.getDefaultPrimitiveValue(method.getReturnType());
        }
        return ret;
    }
    

    相关文章

      网友评论

          本文标题:SOFA RPC客户端源码解析之客户端生成代理类

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