简体   繁体   中英

How to add a private field to class using bytebuddy

I have a class like this

public class SampleClass {

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

I am using Advice for get Metrics of this methods.

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
        }
    }
}
}

I want to add a metrics timer(or any field) from @Advice.OnMethodEnter to SampleClass and get it from @Advice.OnMethodExit Is that can be done? I think my question is clear.

You have to define two classes with each advice method and then apply each advice to the method you want to change. You can define a field using Byte Buddy's type builder 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();

You can now read and write to the foo field using @Advice.Field . You should however be careful due to threading issues.

Also, this cannot be done for a class redefining Java agent as the JVM forbids adding fields to already loaded classes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM