如何使用bytebuddy拦截具有特定参数的方法

时间:2017-09-03 05:46:52

标签: byte-buddy

我想拦截名为methodA的方法,其中一个arg类型为String,我该怎么办。如何使用hasParameters()api?

public class Demo {

    public static void main(String[] args) {

        new ByteBuddy()
                .subclass(A.class)
                .method(named("methodA").and(hasParameters(?)))
    }


    static class A {

        public void methodA() {
            System.out.println("methodA() invoked.");
        }

        public void methodA(String arg) {
            System.out.println("methodA(" + arg + ") invoked.");
        }
    }

}

2 个答案:

答案 0 :(得分:1)

为此您需要ElementMatchers.takesArguments(String.class)匹配器。

类似的东西:

    Class<? extends A> loaded =  new ByteBuddy().subclass(A.class)
       .method(ElementMatchers.named("methodA").and(ElementMatchers.takesArguments(String.class)))
       .intercept(MethodDelegation.to(Demo.class))
       .make().load(Demo.class.getClassLoader(), ClassLoadingStrategy.Default.INJECTION).getLoaded();

    A instance = loaded.getConstructor().newInstance();
    instance.methodA("abc");
    instance.methodA();


public class Demo {

    static void intercept(String arg){
         System.out.println("intercepted");
    }
}

答案 1 :(得分:0)

为澄清起见,您需要定义一个匹配器(类似于过滤器)以应用于方法。在匹配器中创建一些约束,使其仅匹配您指定的某些参数结构:

ElementMatcher<Iterable<? extends ParameterDescription>> matcher = parameterDescriptions -> {
    for (ParameterDescription p : parameterDescriptions) {
        if (p.getType().equals(TypeDescription.STRING.asGenericType()) && p.getIndex() == 0) return true;
    }
    return false;
};

ByteBuddyAgent.install();
new ByteBuddy()
    .redefine(SomeType.class)
    .method(ElementMatchers.hasParameters(matcher))
    .intercept(FixedValue.value("Hello World"))
    .make()
    .load(SomeType.class.getClassLoader(), 
        ClassReloadingStrategy.fromInstalledAgent());