如何使用 bytebuddy 将私有字段添加到 class

How to add a private field to class using bytebuddy

我有一个class这样的

public class SampleClass {

    public void startMethod(int no){
    //some works!!
}
public void endMethod(String name){
    //some works!!
}    
}

我正在使用 Advice 获取此方法的指标。

public class TimerAdvice {

@Advice.OnMethodEnter
static void enter(@Advice.Origin String method){

    if (method.equals("startMethod")) {
        //Metrics works
    }

}

@Advice.OnMethodExit
static void exit(@Advice.Origin String method){
    if (method.equals("endMethod")) {
       //Metrics works
        }
    }
}
}

我想从 @Advice.OnMethodEnter 添加一个度量计时器(或任何字段)到 SampleClass 并从 @Advice.OnMethodExit 获取它 那可以做到吗?我想我的问题很清楚了。

您必须为每个建议方法定义两个 class,然后将每个建议应用于您要更改的方法。您可以使用 Byte Buddy 的类型构建器定义字段 API:

new ByteBuddy()
  .redefine(SampleClass.class)
  .visit(Advice.to(TimerAdviceStart.class).on(named("startMethod"))
  .visit(Advice.to(TimerAdviceEnd.class).on(named("endMethod"))
  .defineField("foo", long.class, Visibility.PRIVATE)
  .make();

您现在可以使用 @Advice.Field 读取和写入 foo 字段。但是,由于线程问题,您应该小心。

此外,无法为 class 重新定义 Java 代理执行此操作,因为 JVM 禁止向已加载的 classes 添加字段。