我想拦截名为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.");
}
}
}
答案 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());