Byte Buddy 在使用 .andThen 时不保留 return 值

Byte Buddy not preserving return value when .andThen used

我正在尝试使用 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" 对象的 return 值,该对象用于对其调用方法更早。我是不是用错了字节好友?

基本上我想在方法的末尾添加一些额外的逻辑(在原始方法内部或添加另一个方法调用无关紧要),但同时保留原始的 return 值方法调用。

这是设计使然。对于您通过 andThen 链接的每个 Implementation,Byte Buddy 期望下一个块的堆栈为空。因此,最后一个实现负责 return.

字节好友的想法是把尽可能多的逻辑放到拦截器中。我建议您编写自己的拦截器来调用委托,然后调用关闭连接。这使您还可以完全控制调用条件,例如在 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