背景: 我的程序使用gRPC进行通信。现在有一些特殊的clints(或存根),我想做一些逻辑(发送Mq消息或将其恢复到数据库中,等等~~)
问题:
public static final class SmsProxyAPIStub extends io.grpc.stub.AbstractAsyncStub<SmsProxyAPIStub> {
private SmsProxyAPIStub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected SmsProxyAPIStub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new SmsProxyAPIStub(channel, callOptions);
}
/**
*/
public void sendSmsMessage1(ird.ntp.be.sms.proto.SendSmsMessageRequest request,
io.grpc.stub.StreamObserver<ird.ntp.be.sms.proto.SendSmsMessageResponse> responseObserver) {
io.grpc.stub.ClientCalls.asyncUnaryCall(
getChannel().newCall(getSendSmsMessageMethod(), getCallOptions()), request, responseObserver);
public void sendSmsMessage2(ird.ntp.be.sms.proto.SendSmsMessageRequest request,
io.grpc.stub.StreamObserver<ird.ntp.be.sms.proto.SendSmsMessageResponse> responseObserver) {
io.grpc.stub.ClientCalls.asyncUnaryCall(
getChannel().newCall(getSendSmsMessageMethod(), getCallOptions()), request, responseObserver);
}
}
客户端类是final修饰的,没有实现任何接口,那我就得选择Byte Buddy(我不熟悉,我的任务已经超时了。)
我试过了:
new ByteBuddy()
.rebase(SmsProxyAPIGrpc.class)
.constructor(ElementMatchers.isPrivate()) // 选择 private 构造函数
.intercept(
MethodCall.invoke(
originalClass.getDeclaredConstructor(Channel.class, CallOptions.class))
.with(channel,callOptions)
) // 调用带参数的原始类构造函
.method(ElementMatchers.nameContains("sendSmsMessage"))
.intercept(MethodDelegation.to(MonitorDemo.class))
.make()
.load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.CHILD_FIRST)
.getLoaded();
但生成的代码确实包含我的增强逻辑, 但当我
Constructor<?> constructor = type.getDeclaredConstructor(Channel.class, CallOptions.class).setAccessible(true);
constructor.newInstance(channel,callOptions);
它让我得到“java.lang.reflect.InitationTargetException:由:ird.ntp.be.sms.proto.SmsProxyAPIGrpc$SmsProxyAPIBlockingStub.(SmsProxyAPIGrpc.java)处的java.lang.StackOverflowError引起”
我想增强SmsProxyAPIGrpc.SmsProxyAPIBlockingStub:
@javax.annotation.Generated(
value = "by gRPC proto compiler (version 1.51.1)",
comments = "Source: ProxyAPI.proto")
@io.grpc.stub.annotations.GrpcGenerated
public final class SmsProxyAPIGrpc {
private SmsProxyAPIGrpc() {}
public static final String SERVICE_NAME = "ird.ntp.be.sms.v1.SmsProxyAPI";
// Static method descriptors that strictly reflect the proto.
private static volatile io.grpc.MethodDescriptor<ird.ntp.be.sms.proto.SendSmsMessageRequest,
ird.ntp.be.sms.proto.SendSmsMessageResponse> getSendSmsMessageMethod;
@io.grpc.stub.annotations.RpcMethod(
fullMethodName = SERVICE_NAME + '/' + "SendSmsMessage",
requestType = ird.ntp.be.sms.proto.SendSmsMessageRequest.class,
responseType = ird.ntp.be.sms.proto.SendSmsMessageResponse.class,
methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
public static io.grpc.MethodDescriptor<ird.ntp.be.sms.proto.SendSmsMessageRequest,
ird.ntp.be.sms.proto.SendSmsMessageResponse> getSendSmsMessageMethod() {
io.grpc.MethodDescriptor<ird.ntp.be.sms.proto.SendSmsMessageRequest, ird.ntp.be.sms.proto.SendSmsMessageResponse> getSendSmsMessageMethod;
if ((getSendSmsMessageMethod = SmsProxyAPIGrpc.getSendSmsMessageMethod) == null) {
synchronized (SmsProxyAPIGrpc.class) {
if ((getSendSmsMessageMethod = SmsProxyAPIGrpc.getSendSmsMessageMethod) == null) {
SmsProxyAPIGrpc.getSendSmsMessageMethod = getSendSmsMessageMethod =
io.grpc.MethodDescriptor.<ird.ntp.be.sms.proto.SendSmsMessageRequest, ird.ntp.be.sms.proto.SendSmsMessageResponse>newBuilder()
.setType(io.grpc.MethodDescriptor.MethodType.UNARY)
.setFullMethodName(generateFullMethodName(SERVICE_NAME, "SendSmsMessage"))
.setSampledToLocalTracing(true)
.setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
ird.ntp.be.sms.proto.SendSmsMessageRequest.getDefaultInstance()))
.setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
ird.ntp.be.sms.proto.SendSmsMessageResponse.getDefaultInstance()))
.setSchemaDescriptor(new SmsProxyAPIMethodDescriptorSupplier("SendSmsMessage"))
.build();
}
}
}
return getSendSmsMessageMethod;
}
/**
* Creates a new async stub that supports all call types for the service
*/
public static SmsProxyAPIStub newStub(io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<SmsProxyAPIStub> factory =
new io.grpc.stub.AbstractStub.StubFactory<SmsProxyAPIStub>() {
@java.lang.Override
public SmsProxyAPIStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new SmsProxyAPIStub(channel, callOptions);
}
};
return SmsProxyAPIStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
public static SmsProxyAPIBlockingStub newBlockingStub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<SmsProxyAPIBlockingStub> factory =
new io.grpc.stub.AbstractStub.StubFactory<SmsProxyAPIBlockingStub>() {
@java.lang.Override
public SmsProxyAPIBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new SmsProxyAPIBlockingStub(channel, callOptions);
}
};
return SmsProxyAPIBlockingStub.newStub(factory, channel);
}
/**
* Creates a new ListenableFuture-style stub that supports unary calls on the service
*/
public static SmsProxyAPIFutureStub newFutureStub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<SmsProxyAPIFutureStub> factory =
new io.grpc.stub.AbstractStub.StubFactory<SmsProxyAPIFutureStub>() {
@java.lang.Override
public SmsProxyAPIFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new SmsProxyAPIFutureStub(channel, callOptions);
}
};
return SmsProxyAPIFutureStub.newStub(factory, channel);
}
/**
* <pre>
* API interface and its request/response messages
* </pre>
*/
public static abstract class SmsProxyAPIImplBase implements io.grpc.BindableService {
/**
*/
public void sendSmsMessage(ird.ntp.be.sms.proto.SendSmsMessageRequest request,
io.grpc.stub.StreamObserver<ird.ntp.be.sms.proto.SendSmsMessageResponse> responseObserver) {
io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSendSmsMessageMethod(), responseObserver);
}
@java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
.addMethod(
getSendSmsMessageMethod(),
io.grpc.stub.ServerCalls.asyncUnaryCall(
new MethodHandlers<
ird.ntp.be.sms.proto.SendSmsMessageRequest,
ird.ntp.be.sms.proto.SendSmsMessageResponse>(
this, METHODID_SEND_SMS_MESSAGE)))
.build();
}
}
/**
* <pre>
* API interface and its request/response messages
* </pre>
*/
public static final class SmsProxyAPIStub extends io.grpc.stub.AbstractAsyncStub<SmsProxyAPIStub> {
private SmsProxyAPIStub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected SmsProxyAPIStub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new SmsProxyAPIStub(channel, callOptions);
}
/**
*/
public void sendSmsMessage(ird.ntp.be.sms.proto.SendSmsMessageRequest request,
io.grpc.stub.StreamObserver<ird.ntp.be.sms.proto.SendSmsMessageResponse> responseObserver) {
io.grpc.stub.ClientCalls.asyncUnaryCall(
getChannel().newCall(getSendSmsMessageMethod(), getCallOptions()), request, responseObserver);
}
}
/**
* <pre>
* API interface and its request/response messages
* </pre>
*/
public static final class SmsProxyAPIBlockingStub extends io.grpc.stub.AbstractBlockingStub<SmsProxyAPIBlockingStub> {
private SmsProxyAPIBlockingStub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected SmsProxyAPIBlockingStub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new SmsProxyAPIBlockingStub(channel, callOptions);
}
/**
*/
public ird.ntp.be.sms.proto.SendSmsMessageResponse sendSmsMessage(ird.ntp.be.sms.proto.SendSmsMessageRequest request) {
return io.grpc.stub.ClientCalls.blockingUnaryCall(
getChannel(), getSendSmsMessageMethod(), getCallOptions(), request);
}
}
/**
* <pre>
* API interface and its request/response messages
* </pre>
*/
public static final class SmsProxyAPIFutureStub extends io.grpc.stub.AbstractFutureStub<SmsProxyAPIFutureStub> {
private SmsProxyAPIFutureStub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected SmsProxyAPIFutureStub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new SmsProxyAPIFutureStub(channel, callOptions);
}
/**
*/
public com.google.common.util.concurrent.ListenableFuture<ird.ntp.be.sms.proto.SendSmsMessageResponse> sendSmsMessage(
ird.ntp.be.sms.proto.SendSmsMessageRequest request) {
return io.grpc.stub.ClientCalls.futureUnaryCall(
getChannel().newCall(getSendSmsMessageMethod(), getCallOptions()), request);
}
}
private static final int METHODID_SEND_SMS_MESSAGE = 0;
private static final class MethodHandlers<Req, Resp> implements
io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
private final SmsProxyAPIImplBase serviceImpl;
private final int methodId;
MethodHandlers(SmsProxyAPIImplBase serviceImpl, int methodId) {
this.serviceImpl = serviceImpl;
this.methodId = methodId;
}
@java.lang.Override
@java.lang.SuppressWarnings("unchecked")
public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
switch (methodId) {
case METHODID_SEND_SMS_MESSAGE:
serviceImpl.sendSmsMessage((ird.ntp.be.sms.proto.SendSmsMessageRequest) request,
(io.grpc.stub.StreamObserver<ird.ntp.be.sms.proto.SendSmsMessageResponse>) responseObserver);
break;
default:
throw new AssertionError();
}
}
@java.lang.Override
@java.lang.SuppressWarnings("unchecked")
public io.grpc.stub.StreamObserver<Req> invoke(
io.grpc.stub.StreamObserver<Resp> responseObserver) {
switch (methodId) {
default:
throw new AssertionError();
}
}
}
private static abstract class SmsProxyAPIBaseDescriptorSupplier
implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier {
SmsProxyAPIBaseDescriptorSupplier() {}
@java.lang.Override
public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() {
return ird.ntp.be.sms.proto.SmsProxyServiceProto.getDescriptor();
}
@java.lang.Override
public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() {
return getFileDescriptor().findServiceByName("SmsProxyAPI");
}
}
private static final class SmsProxyAPIFileDescriptorSupplier
extends SmsProxyAPIBaseDescriptorSupplier {
SmsProxyAPIFileDescriptorSupplier() {}
}
private static final class SmsProxyAPIMethodDescriptorSupplier
extends SmsProxyAPIBaseDescriptorSupplier
implements io.grpc.protobuf.ProtoMethodDescriptorSupplier {
private final String methodName;
SmsProxyAPIMethodDescriptorSupplier(String methodName) {
this.methodName = methodName;
}
@java.lang.Override
public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() {
return getServiceDescriptor().findMethodByName(methodName);
}
}
private static volatile io.grpc.ServiceDescriptor serviceDescriptor;
public static io.grpc.ServiceDescriptor getServiceDescriptor() {
io.grpc.ServiceDescriptor result = serviceDescriptor;
if (result == null) {
synchronized (SmsProxyAPIGrpc.class) {
result = serviceDescriptor;
if (result == null) {
serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
.setSchemaDescriptor(new SmsProxyAPIFileDescriptorSupplier())
.addMethod(getSendSmsMessageMethod())
.build();
}
}
}
return result;
}
}
我需要一些帮助。 祝你好运发财
Class<?> type =
new ByteBuddy()
.rebase(SmsProxyAPIGrpc.SmsProxyAPIBlockingStub.class)
.constructor(ElementMatchers.isPublic())
.intercept(
MethodCall.invoke(
originalClass.getDeclaredConstructor(Channel.class, CallOptions.class))
.with(channel,callOptions)
) // 调用带参数的原始类构造函
.method(ElementMatchers.nameContains("sendSmsMessage"))
.intercept(MethodDelegation.to(MonitorDemo.class))
.make()
.load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.CHILD_FIRST_PERSISTENT)
.getLoaded();
It can work this way.The key is to make constructor public and mind the classloader.