> 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(); //返回服务端执行结果
}
~~~