Search code examples
javabytecodeinstrumentationbyte-buddy

Pass argument to bytebuddy interceptor


I have an interceptor using Byte Buddy and I want to pass an argument to the interceptor. How can I do this?

ExpressionHandler expressionHandler = ... // a handler 
Method method = ... // the method that will be intercepted
ByteBuddy bb = new ByteBuddy();
bb.subclass(theClazz)
   .method(ElementMatchers.is(method))
   .intercept(MethodDelegation.to(MethodInterceptor.class));
   .make()
   .load(theClazz.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER);

The intercepting method in MethodInterceptor is:

@RuntimeType
public static Attribute intercept(@Origin Method method, @AllArguments Object[] args) throws Exception {       
    String name = method.getName();
    Class<? extends Attribute> type = (Class<? extends Attribute>) method.getReturnType();
    ExpressionHandler expressionHandler= // ??? 
    expressionHandler.attachStuff(name, type);
    return expressionHandler;
}

How can I pass the expressionHandler from the builder to the interceptor method?


Solution

  • Simply use instance delegation instead of class-level delegation:

    MethodDelegation.to(new MethodInterceptor(expressionHandler))
    

    with

    public class MethodInterceptor {
    
      private final ExpressionHandler expressionHandler;
    
      public MethodInterceptor(ExpressionHandler expressionHandler) {
        this.expressionHandler = expressionHandler;
      }
    
      @RuntimeType
      public Attribute intercept(@Origin Method method, @AllArguments Object[] args) throws Exception {       
        String name = method.getName();
        Class<? extends Attribute> type = (Class<? extends Attribute>) method.getReturnType();
        this.expressionHandler.attachStuff(name, type);
        return expressionHandler;
      }
    }