如何使用ByteBuddy来测量通过代理人注释的注释标记方法所花费的时间

时间:2017-03-07 14:43:26

标签: byte-buddy

我正在使用ByteBuddy对certian方法进行一些性能测量。因此,我正在诠释那些有趣的人。由于方法签名不稳定,我选择拦截器的通用方法:

public class ChronometryInterception {

  @RuntimeType
  public Object intercept(@Origin MethodHandle methodHandle, @AllArguments Object[] allArguments, @Origin Method method) throws Exception {
    System.out.println("in interceptor");
    long startTime = System.currentTimeMillis();
    try {
        return methodHandle.invoke(allArguments);
    } catch (Throwable e) {
        System.out.println("ex in interceptor " + e.getMessage());
        throw new Exception(e);
    } finally {
        long elapsedTime = System.currentTimeMillis() - startTime;
        System.out.println("took " + elapsedTime;

    }
  }
}

我将它绑定在我的premain()中,就像这样

ChronometryInterception chronometryInterception = new ChronometryInterception();

new AgentBuilder.Default()
    .with(AgentBuilder.Listener.StreamWriting.toSystemOut())
    .type(declaresMethod(isAnnotatedWith(Timed.class)))
      .transform((builder, type, classLoader, module) -> builder
        .method(isAnnotatedWith(Timed.class))
                 .intercept(MethodDelegation.to(chronometryInterception))
      ).installOn(instrumentation);

在监听器流中,我可以看到已注释的类已被转换,并且它们尝试执行某些操作,但最终会使用NPE。使用调试器,我没有在ChronometryInterception中获得任何地方。任何出路?谢谢!

1 个答案:

答案 0 :(得分:1)

我找到了一个有效的解决方案。最后,拦截器的方法签名不行。即使有ChronometryInterception的实例,这个也在工作:

public class ChronometryInterception {

  @RuntimeType
  public Object intercept(@SuperCall Callable<?> zuper) throws Exception {
    long startTime = System.currentTimeMillis();
    try {
        return zuper.call();
    } catch (Exception e) {
        throw e;
    } finally {
      long elapsedTime = System.currentTimeMillis() - startTime;
      System.out.println("took " + elapsedTime);
    }
  }

}