gpt4 book ai didi

java - 使用 Byte Buddy 创建自定义方法签名的高效方法

转载 作者:行者123 更新时间:2023-11-30 11:06:05 24 4
gpt4 key购买 nike

我正在尝试使用 ByteBuddy 实现 Profiler。我目前正在努力有效地为我正在分析的方法创建适当的签名。

这是我当前实现的要点:https://gist.github.com/felixbarny/e0c64819c59368a28200

ProfilingInterceptor.profile 方法有两种实现方式。每个人都有自己的缺点。

第一个使用@Origin String signature作为签名。这非常有效,因为 ByteBuddy 似乎缓存了它。问题是,我对签名的格式不满意。例如 method2(I)I

在第二个实现中,我注入(inject)了 @Origin(cacheMethod = true) Method method 并手动构建了一个更好看的签名:int org.stagemonitor.benchmark.profiler.ClassJavasistProfiled.method2 (整数)。明显的问题是每次调用时都会重新创建签名 - 性能不佳(我的 jmh 基准测试说它慢了 4 倍)。

有没有办法缓存签名,例如为每个签名创建一个字符串常量?

提前致谢

最佳答案

完成您想要的最简单方法是实现您自己的注释并创建绑定(bind)。任何这样的 String 值都会被添加到类的常量池中,并从那里简单地返回。

你可以找到一个 example for creating a custom annotation在 Byte Buddy 教程的底部。要实现自定义 @Signature 注释,您需要执行以下操作:

enum SignatureBinder
implements TargetMethodAnnotationDrivenBinder.ParameterBinder<StringValue> {

INSTANCE; // singleton

@Override
public Class<Signature> getHandledType() {
return Signature.class;
}

@Override
public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loaded<StringValue> annotation,
MethodDescription source,
ParameterDescription target,
Instrumentation.Target instrumentationTarget,
Assigner assigner) {
if (!target.getTypeDescription().represents(String.class)) {
throw new IllegalStateException(target + " makes illegal use of @Signature");
}
StackManipulation constant = new TextConstant("<signature goes here>");
return new MethodDelegationBinder.ParameterBinding.Anonymous(constant);
}
}

名为sourceMethodDescription 对象描述了拦截的方法并提供了一个类似于Method 类的接口(interface)。然后,您可以使用 MethodDelegation 注册此 Binder ,然后您可以在委托(delegate)中使用注释。

旁注:我会避免使用规范名称。这些名称可能会相互冲突,例如类

foo.Bar$Qux
foo.Bar.Qux

Bar 曾经是一个具有内部类 Qux 的类,曾经是一个具有相同名称的类 Qux 的包。我知道这不太可能,但您永远不知道用户代码会是什么样子。

关于java - 使用 Byte Buddy 创建自定义方法签名的高效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29415235/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com