当前位置: 首页 > 面试题库 >

在运行时使用Byte Buddy添加方法注释

习旻
2023-03-14
问题内容

我一直在寻找“如何在运行时向方法添加注释”的答案,发现了一个名为Byte
Buddy的出色工具,可以使用它,但仍然无法按需使用。我确定它必须能够从这个问题做到这一点Byte
Buddy可以在运行时创建字段和方法注释吗?

上这堂课:

public class ClassThatNeedsToBeAnnotated {
  public void method(int arg1, String arg2) {
    // code that we don't want to touch at all, leave it as is
    System.out.println("Called method with arguments " + arg1 + " " + arg2);
  }

  public void method() {
    System.out.println("Called method without arguments");
  }
}

和此代码:

 public class MainClass {
      public static void main(String[] args) {
        ByteBuddyAgent.install();

        AnnotationDescription description = AnnotationDescription.Builder.ofType(MyClassAnnotation.class)
            .define("value", "new")
            .build();

        new ByteBuddy()
            .redefine(ClassThatNeedsToBeAnnotated.class)
            .annotateType(description)
            .make()
            .load(ClassThatNeedsToBeAnnotated.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());

      }
}

添加注释很容易。但是对于 方法而言 ,似乎不更改方法实现是不可能的。

Method existingMethod = ClassThatNeedsToBeAnnotated.class.getDeclaredMethods()[0];
AnnotationDescription annotationDescription = AnnotationDescription.Builder.ofType(MyMethodAnnotation.class)
    .build();
new ByteBuddy()
    .redefine(ClassThatNeedsToBeAnnotated.class)
    .annotateType(description)
    .method(ElementMatchers.anyOf(existingMethod))
    // here I don't want to intercept method, I want to leave the method code untouched. How to do that?
    .annotateMethod(annotationDescription)
    .make()
    .load(ClassThatNeedsToBeAnnotated.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());

我敢肯定,我只是做得不好,但是不幸的是,当方法 没有代码更改 而只有注释更改时,找不到示例。


问题答案:

您在Byte Buddy中发现了一个盲点,我想修复一会儿。早期版本的Byte
Buddy不允许定义注释,但是当它允许时,该API已经被广泛使用,以至于我无法更改它,并且在实现中也需要一些位。

如果您愿意为添加合成方法付出最小的代价,则可以改类为基础:

new ByteBuddy().rebase(ClassThatNeedsToBeAnnotated.class)

这样做,您可以仅使用当前的API并添加的实现SuperMethodCall。这将在重新基准化中调用完全相同的方法。

此处跟踪了Byte Buddy的增强功能:https://github.com/raphw/byte-
buddy/issues/627

更新 :在即将发布的字节好友1.10.0中,可以通过以下方式实现:

new ByteBuddy()
  .redefine(ClassThatNeedsToBeAnnotated.class)
  .visit(new MemberAttributeExtension.ForMethod()
    .annotateMethod(someAnnotation)
    .on(matcher))
  .make();

注释实例可以通过以下方式获取:
AnnotationDescription.Latent.Builder.ofType(AnnotationClass.class).build()



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

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

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

  • 我知道ApplicationContext扩展点,如ApplicationContext事件和BeanFactoryPostProcessor。 我手头的问题是,在创建了一些bean之后,我需要添加bean,我想这会丢弃BeanFactoryPostProcessor选项,因为在应用程序上下文开始注册bean之前会发生这种情况。 我尝试在上下文刷新后添加一个singletonBean:

  • 问题内容: 而且我正在尝试更改方法注释,但是java.lang.reflect.Method不包含任何地图字段(例如“ annotations”)或方法(例如“ getDeclaredAnnotationMap”) 只有但是我可以用这个字节数组做什么? 那么,如何修改方法的注释呢? 编辑: 我创建了:http : //pastebin.com/T2rewcwU 但是,仅编辑此方法实例,如果取消注释

  • 我已经浏览了之前关于在运行时添加Log4j2附加器的线程,但没有一个真正适合我的场景。 我们将一个长时间运行的Flink作业打包到一个胖jar中,我们基本上将其提交给一个运行的Flink集群。我们想把错误日志转发给哨兵。很方便,Sentry提供了一个我希望能够使用的Log4j2 appender,但所有让Log4j2工作的尝试都失败了——对此有点疯狂(花了几天时间)。 因为Flink(也使用log