使用 bytebuddy 实现方法检测

问题描述 投票:0回答:1

我们正在尝试构建一个 javaagent,用于使用 ByteBuddy 来检测类。我们有一个 javassist 实现,它不能很好地与 Mockito 配合使用,因此转向 ByteBuddy 进行检测。

使用 DynamicType$Builder,我们需要检测所选类的方法,具体取决于该方法是构造函数、类初始值设定项还是任何其他方法。

此外,beforeMethod 拦截器方法有一个需要为每个方法唯一生成的参数。 afterMethod 拦截器方法是零参数方法。所以,我们需要:

  1. 为每个检测方法创建一个 MethodCall 实例,用于方法输入。
  2. 创建一个所有检测方法通用的 MethodCall 实例,用于方法退出。

方法调用是这样的:

        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 没有简单的方法来做到这一点,我需要为每个方法添加一个常量,并注入字节代码来引用它。

java instrumentation byte-buddy
1个回答
0
投票

这个问题已经由库的作者在这篇文章中回答了。

如何将变量传递给advice?

此外,我们需要迭代每个方法并应用自定义映射。

问题也发布在这里: https://mail.google.com/mail/u/0/#inbox/FMfcgzGtxdSWCWPxhkhJddXqpngjxZFB

© www.soinside.com 2019 - 2024. All rights reserved.