我正在尝试使用Byte Buddy在方法完成时执行一些额外的逻辑。以下是示例代码:
T proxyClient = JAXRSClientFactory.fromClient(client, classType, true);
this.configureHttpConduit(conduit, invocationTimeout);
Class buddy = new ByteBuddy()
.subclass(classType)
.method(ElementMatchers.isAnnotatedWith(Path.class))
.intercept(MethodDelegation.to(proxyClient)
.andThen(MethodCall.run(new CloseConnection())))
.make()
.load(this.getClass().getClassLoader(),
Default.INJECTION)
.getLoaded();
return (T) buddy.newInstance();
static class CloseConnection implements Runnable {
void close() {
System.out.println("close connection called");
}
@Override
public void run() {
close();
}
}
当我使用.andThen调用链接委托时,此实例的原始调用者将丢失来自“proxyClient”对象的返回值,该对象之前用于调用方法调用。我使用Byte Buddy错了吗?
基本上我想在方法的末尾添加一些额外的逻辑(在原始方法内部或添加另一个方法调用无关紧要),但同时保留原始方法调用的返回值。
答案 0 :(得分:1)
这是设计的。对于通过Implementation
链接的每个andThen
,Byte Buddy期望下一个块的空堆栈。因此,最后一个实现负责返回。
Byte Buddy的想法是尽可能多地将逻辑放入拦截器中。我建议你编写自己的拦截器来调用委托,然后调用close连接。这使您可以完全控制调用条件,例如关闭finally块:
public class MyInterceptor<T> {
final T proxyClient;
@RuntimeType
public Object intercept(@Origin Method method,
@AllArguments Object[] args) throws Throwable {
try {
return method.invoke(proxyClient, args);
} finally {
// do your completion logic here
}
}
}
这当然可以在性能方面得到改善。请查看@Pipe annotation。