как перехватить метод с определенными параметрами с помощью bytebuddy

Я хочу перехватить метод с именем methodA с одним аргументом типа String как удар, что мне делать. Как использовать API hasParameters()?

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.");
        }
    }

}

person MengZhi    schedule 03.09.2017    source источник


Ответы (2)


Для этого вам нужен сопоставитель 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");
    }
}
person k5_    schedule 03.09.2017
comment
Большое спасибо. Я использую метод ElementMatchers.hasParameters и реализую ElementMatcher‹Iterable‹? расширяет интерфейс ParameterDescription›› для достижения моей цели, и это работает хорошо. - person MengZhi; 05.09.2017

Чтобы уточнить, вам нужно определить сопоставитель (похожий на фильтр) для применения к методам. Создайте некоторое ограничение в сопоставителе, чтобы оно соответствовало только указанной вами структуре параметров:

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());
person ryan    schedule 04.07.2019