当前位置: 首页 > 知识库问答 >
问题:

ByteBuddy:如何在转换方法时跨Enter/Exit添加局部变量

傅宏恺
2023-03-14

因此,我尝试使用ByteBuddy的能力来创建可以从@Advice.onMethodEnter保留到@Advice.onMethodExit的局部变量。这将允许我在方法enter上创建OpenTracing跨度,并在方法Exit上完成它。不过,我不确定我的用例是否有效,因为我使用的是一个转换器,它与@advice.local注释的测试用例不完全匹配。

我试图遵循这个测试用例中使用的语法。

但是,span和scope变量在exit方法中始终为null。我是ByteBuddy的新手,所以我肯定我错过了一些基本的东西。

public class SimpleFrameworkDispatcherAgentRule extends AgentRule {
    @Override
    public Iterable<? extends AgentBuilder> buildAgent(AgentBuilder agentBuilder) {
        return Arrays.asList(agentBuilder
                .type(named("org.simpleframework.http.core.Dispatcher"))
                .transform((builder, typeDescription, classLoader, module) -> {
                    return builder.visit(Advice.to(SimpleFrameworkDispatcherAgentRule.class)
                            .on(named("dispatch")));
                }));
    }

    @Advice.OnMethodEnter
    public static void enter(final @Advice.Origin String origin, 
            final @FieldValue(value = "request", typing = Typing.DYNAMIC) Object request, 
            final @Advice.Local("span") Object span, 
            final @Advice.Local("scope") Object scope) {
        if (isEnabled(origin)) {
            SimpleFrameworkAgentIntercept.enter(request, span, scope);
        }
    }

    @Advice.OnMethodExit
    public static void exit(final @Advice.Origin String origin, 
            final @FieldValue(value = "response", typing = Typing.DYNAMIC) Object response, 
            final @Advice.Local("span") Object span, 
            final @Advice.Local("scope") Object scope) {
        if (isEnabled(origin)) {
            SimpleFrameworkAgentIntercept.exit(response, span, scope);
        }
    }
}

我检测了SimpleFrameworkAgentIntercept enter和exit方法,并确认变量在enter中赋值,但在exit中为null。

共有1个答案

厉成仁
2023-03-14

您必须赋值变量,如果您在委托方法中这样做,它没有帮助。

Byte Buddy使用通知代码作为模板,在该模板中,对特定方法中的局部变量的任何赋值都被转换为对内联字节代码中检测的局部变量的访问。

Java没有C或其他语言意义上的指针语义。如果要分配spanscope,则必须在带注释的方法本身中进行。

 类似资料:
  • 我正在使用ByteBuddy实现字节码转换,操作过程是一个多步骤的过程。因此,操作必须能够: 扩充原有方法 对于1。我使用了一个通过以下方式应用的OnMethodExit建议: 使用方法的增强代码(有效地设置字段的值)。创建新方法时,我按如下方式构建它们: 通过以为参数的静态方法使用运行时实例。 简而言之:如果前面的转换遵循后者,我看不到前面的转换应用。实际执行顺序如下: 我的类型得到处理,并通过

  • 我目前正在尝试使用ByteBuddy作为java bean实现包装键/值对的,将map键公开为普通getter/setter。 我最初按照如下方式构造生成器,允许我将

  • 问题内容: 嗨,我正在浏览有关内部类的SCJP书,发现了这一说法,类似这样。 方法本地类只能引用已标记的本地变量 在解释中,指定的原因与本地类对象和堆上的局部变量的范围和生存期有关,但我无法理解。我在这里想念任何东西吗? 问题答案: 原因是,在创建方法本地类实例时,编译器实际上会将其引用的所有方法本地变量复制到其中。这就是为什么只能访问变量的原因。甲变量或参考是不变的,所以它停留在同步与其方法本地

  • 我只需要添加一个边距顶部,这样,如果我的图像是用这个js: 我知道这可能很简单,但我是个初学者。希望有人能教我怎么做。谢谢!

  • 使用ByteBuddy,我可以通过调用另一个实例方法并转换结果来实现一个实例方法吗? 例如(玩具): 鉴于上述情况,我能否实现,以便它调用并返回返回字符串的长度?也就是说,好像它是: 我天真地尝试了以下方法: 然而,看起来我的想法是错误的,;它看起来像是在生成的实例上调用的。 我还试过一个拦截器: 与: 这运行了,但产生了毫无意义的结果,在中设置断点和/或添加打印语句表明它永远不会被调用;所以很明

  • 问题内容: 我正在使用函数,这样我的程序就不会一团糟,但我不知道如何将局部变量变成全局变量。 问题答案: 这是两种实现相同目的的方法: 使用参数并返回(推荐) 运行时,将获得以下输出 使用全局变量(永远不要这样做) 现在您将获得: