javabyte-buddy

Byte Buddy Advice Custom Object


I'm trying to use byte buddy and I appreciate your help for the below: Given that I have the following class

public class MyAdvice {
    private String param1;
    private Object param2;

    public MyAdvice(String param1, Object param2) {
        this.param1 = param1;
        this.param2 = param2;
    }
}

I want to pass this to my interceptor, is this possible? I've read about binding the value to an annotation I think I am missing someting, as I was only able to make it work with String class

MyAdvice[] myAdvice = new MyAdvice[1];
myAdvice[0] = new MyAdvice("123", new Object());
builder.method(ElementMatchers.named(setterMethodName)
       .and(ElementMatchers.takesArguments(1)))
       .intercept(Advice.withCustomMapping()
       .bind(Custom.class, myAdvice)
       .to(SetterInterceptor.class))
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Custom { }
public class SetterInterceptor {
    public static void intercept(@Argument(0) Object value @Custom MyAdvice[] myAdvice) {
        // custom code, do something with myAdvice
    }
}

Is something like this possible?

@Custom MyAdvice[] myAdvice

Solution

  • In theory, any serializable value can be assigned to an annotated parameter. However, values would loose identity, such as your new Object(). It is however rarely recommended to do this, I would rather create a custom StackManipulation that creates the relevant values.

    If applicable, you can also add a field to the instrumented class and define a fixed value as the field's value. This would preserve the identity, but alter the field.

    As a last option, you can define a carrier class where you store the values in some map that is globally available. The you could create some random string like a UUID value. This key can serve as a lookup key in this map which you then use in your advice to resolve the actual value.