Sofa-rpc的版本5.6.1
RPC調用,基本都會涉及到代理,通過代理封裝接口的實現。
如下Proxy接口就是Sofa中對代理的抽象,具體的實現類有JDK代理、javassist實現代理、bytebuddy實現代理。
List-1
@Extensible
public interface Proxy {
/**
* 生成代理對象
*
* @param interfaceClass 接口類
* @param proxyInvoker Invoker
* @param <T> 類型
* @return 代理對象
*/
<T> T getProxy(Class<T> interfaceClass, Invoker proxyInvoker);
/**
* 從代理對象裏解析Invoker
*
* @param proxyObject 代理對象
* @return Invoker
*/
Invoker getInvoker(Object proxyObject);
}
JDKProxy如下,是JDK代理的實現,代理了接口,具體實現在JDKInvocationHandler中
List-2
@Extension("jdk")
public class JDKProxy implements Proxy {
@Override
public <T> T getProxy(Class<T> interfaceClass, Invoker proxyInvoker) {
InvocationHandler handler = new JDKInvocationHandler(interfaceClass, proxyInvoker);
ClassLoader classLoader = ClassLoaderUtils.getCurrentClassLoader();
T result = (T) java.lang.reflect.Proxy.newProxyInstance(classLoader,
new Class[] { interfaceClass }, handler);
return result;
}
@Override
public Invoker getInvoker(Object proxyObject) {
return parseInvoker(proxyObject);
}
/**
* Parse proxy invoker from proxy object
*
* @param proxyObject Proxy object
* @return proxy invoker
*/
public static Invoker parseInvoker(Object proxyObject) {
InvocationHandler handler = java.lang.reflect.Proxy.getInvocationHandler(proxyObject);
if (handler instanceof JDKInvocationHandler) {
return ((JDKInvocationHandler) handler).getProxyInvoker();
}
return null;
}
}
JDKInvocationHandler的實現如下List-3,將調用的方法簽名封裝到SofaRequest中,之後調用ProxyInvoker.invoke,ProxyInvoker是一個鏈,類似J2EE中的Filter。 返回的SofaResponse,獲取到服務提供者的響應後,如果是異常,則直接拋出,如果結果是Null且是JDK的基礎類,則返回默認值。
List-3
@Override
public Object invoke(Object proxy, Method method, Object[] paramValues)
throws Throwable {
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);
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;
}
}
所以重點在於JDKInvocationHandler中的ProxyInvoker的實現。