- 时序
说明:
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;
}
网友评论