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

  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           类型
     * @return 代理类实例
     * @throws Exception
     */
    public static  T buildProxy(String proxyType, Class clazz, Invoker proxyInvoker) throws Exception {
        try {
            ExtensionClass 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客户端源码解析之客户端生成代理类)