> anoyi中的GrpcServiceProxy
1. 簡述(代理類proxy)
這是個代理類是代理GrpcService注解的類,封裝了GrpcService,在調用GrpcService的所有方法前,會Aop自己的的代理方法的類
2. 查看GrpcServiceProxy的屬性
~~~
private Class<T> grpcService; //實際被代理的類
private Object invoker; //普通object
~~~
3. 查看GrpcServiceProxy的構造方法
~~~
public GrpcServiceProxy(Class<T> grpcService, Object invoker) {
this.grpcService = grpcService;
this.invoker = invoker;
}
~~~
4. 查看GrpcServiceProxy的主要方法(GrpcServiceProxy實現了InvocationHandler,所以必須實現invoke,invoke在調用代理對象方法時候會先執行invoke,再執行被代理的對象方法,實現Aop,但是這方法里面的method沒有調用,也沒有調用proxy,而是直接通過GrpcClient靜態方法,發給服務端調用服務端的方法,這就實現了客戶端遠程通知服務端調用客戶端所需的方法,也是grpc的核心)
~~~
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName(); //被代理的類中被實際調用方法,這個方法會被封裝到request發送給服務端,實現遠程調用,并返回結果給客戶端
String className = grpcService.getName(); //被代理的類名
if ("toString".equals(methodName) && args.length == 0) {
return className + "@" + invoker.hashCode(); //toString方法就執行返回
} else if ("hashCode".equals(methodName) && args.length == 0) {
return invoker.hashCode(); //hashCode方法就執行返回
} else if ("equals".equals(methodName) && args.length == 1) {
Object another = args[0]; //equals方法就執行返回
return proxy == another;
}
GrpcService annotation = grpcService.getAnnotation(GrpcService.class); //取出注解類GrpcService
String server = annotation.server(); //注解類GrpcService的server,代表遠程調用的服務器名
GrpcRequest request = new GrpcRequest();
request.setClazz(className); //遠程調用的類名
request.setMethod(methodName); //遠程調用的方法名
request.setArgs(args); //遠程調用的參數
SerializeType[] serializeTypeArray = annotation.serialization(); //注解類GrpcService的序列化實現類型
SerializeType serializeType = null;
if (serializeTypeArray.length > 0) {
serializeType = serializeTypeArray[0]; //取出序列化類型,方便調用序列化方法
}
GrpcResponse response = GrpcClient.connect(server).handle(serializeType, request); //grpc遠程請求,http2.0
if (GrpcResponseStatus.ERROR.getCode() == response.getStatus()) { //服務端返回錯誤堆棧
Throwable throwable = response.getException();
GrpcException exception = new GrpcException(throwable.getClass().getName() + ": " + throwable.getMessage());
StackTraceElement[] exceptionStackTrace = exception.getStackTrace();
StackTraceElement[] responseStackTrace = response.getStackTrace();
StackTraceElement[] allStackTrace = Arrays.copyOf(exceptionStackTrace, exceptionStackTrace.length + responseStackTrace.length);
System.arraycopy(responseStackTrace, 0, allStackTrace, exceptionStackTrace.length, responseStackTrace.length);
exception.setStackTrace(allStackTrace);
throw exception;
}
return response.getResult(); //返回服務端執行結果
}
~~~