当.andThen使用时,Byte Buddy不保留返回值

时间:2018-01-28 00:04:51

标签: java byte-buddy

我正在尝试使用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错了吗?

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

1 个答案:

答案 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