问题描述
是否可以通过将执行替换为 lambda 表达式或其他类的非静态方法来拦截方法?
例 1:
installByteBuddyAgent();
byteBuddy
.redefine(sourceClass) //This is important,i need to change a class deFinition
.method(named(methodName))
.intercept({{expression}})
.make()
.load(
sourceClass.getClassLoader(),ClassReloadingStrategy.fromInstalledAgent());
//expression = Lambda expression that would be executed in place of the original method,or call a (non-static) method from some other class.
例 2:
public class A {
public void sayHello() {
System.out.println("Hello");
}
}
public class B {
public void sayGoodbye() {
System.out.println("Goodbye");
}
}
// ...
@Test
void interceptAReplacingByB() {
final Class<A> sourceClass = A.class;
final B b = Mockito.spy(new B());
byteBuddy
.redefine(sourceClass)
.method(named("sayHello"))
.intercept( /*call sayGoodbye from B or create a lambda expression to do it*/ )
.make()
.load(
sourceClass.getClassLoader(),ClassReloadingStrategy.fromInstalledAgent());
new A().sayHello();
Mockito.verify(b).sayGoodbye();
}
此代码片段并不代表完整的场景。它只是为了举例说明问题而构建的。
可以通过其他方式拦截公共方法,但目的不是只适用于公共方法,也不是只适用于测试场景。
解决方法
如果我对你的理解正确:
// ...
.intercept(net.bytebuddy.implementation.MethodCall.invoke("sayGoodbye").on(b))
// ...
注意 a static
field will be defined in your reimplementation of A
to hold the instance of b
。