我们正在尝试构建一个 javaagent,用于使用 ByteBuddy 来检测类。我们有一个 javassist 实现,它不能很好地与 Mockito 配合使用,因此转向 ByteBuddy 进行检测。
使用 DynamicType$Builder,我们需要检测所选类的方法,具体取决于该方法是构造函数、类初始值设定项还是任何其他方法。
此外,beforeMethod 拦截器方法有一个需要为每个方法唯一生成的参数。 afterMethod 拦截器方法是零参数方法。所以,我们需要:
方法调用是这样的:
private static MethodCall getInsertBefore(Method method) {
//construct a murmur32 hash using the method's class name, name, and signature.
int murmur32Hash = ...;
return MethodCall.invoke(named("beforeMethod"))
.on(SomeClass.class)
.withReference(murmur32Hash);
}
private static MethodCall getInsertAfter() {
return MethodCall.invoke(named("afterMethod")).on(SomeClass.class);
}
带注解的类:
public class SomeClass {
@Advice.OnMethodEnter
public static void beforeMethod(int murmur32HashCode) {
/*murmur32HashCode is generated during transformation and not selected from argument list*/
...
}
@Advice.OnMethodExit
public static void afterMethod() {
...
}
}
使用DynamicType$Builder,有什么方法可以访问所有声明的方法,并为每个方法创建上面提到的MethodCall实例,以便在该方法之前和之后调用?
Javassist 提供了一种直观的方法来做到这一点。对于 ByteBuddy,在我在网上找到的几乎所有示例中,拦截都涉及指定一个带有注释方法的类,并带有从正在检测的方法的调用中选择的注释方法的参数(没有新生成的值)。
我浏览了 ByteBuddy 代码,似乎可以使用 MethodVisitor 类,尽管我在尝试理解代码序列时迷失了方向。
发现如果我们使用自定义映射,我们可以为注释指定一个自定义值,该值可以在拦截器中引用。 但是,它不能用于为每个检测方法设置自定义值。 也许,使用 ByteBuddy 没有简单的方法来做到这一点,我需要为每个方法添加一个常量,并注入字节代码来引用它。
这个问题已经由库的作者在这篇文章中回答了。
此外,我们需要迭代每个方法并应用自定义映射。
问题也发布在这里: https://mail.google.com/mail/u/0/#inbox/FMfcgzGtxdSWCWPxhkhJddXqpngjxZFB