バイトバディで、実行時にメソッドのアノテーションを追加

lub0v:

私はすでに数日間、「実行時にメソッドに注釈を追加する方法」への答えを探してとバイトバディと呼ばれるこの素晴らしいツールを見つけ、それを果たしたが、それでも私が必要として、それを動作させることはできませんしました。私はこの質問から、それを行うことができなければならないと確信している缶バイトバディは、実行時にフィールドやメソッドのアノテーションを作成しますか?

このクラスを持ちます:

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());

私は確かに、私はただ存在しない場合の一例を見つけることができません、残念ながら右のそれを行うが、していないことだよ何のコード変更方法のみ注釈の変更のために。

ラファエル・ヴィン:

あなたは、私はしばらくの間、固定と考えていることバイトバディでblindspotを発見しました。バイトバディの初期のバージョンでは、アノテーションを定義することができませんでしたが、それがなかったとき、APIはまだ広く、あまりにも、私はそれを変更することができませんでしたし、それが実装にいくつかのビットを必要とすることに使用しました。

あなたは、合成方法を追加し、最小限の価格を支払うことを喜んでいる場合は、代わりにクラスをリベースすることができます:

new ByteBuddy().rebase(ClassThatNeedsToBeAnnotated.class)

そう、あなただけの現在のAPIを使用しての実装を追加することができますSuperMethodCallこれはrebasementで非常に同じメソッドを呼び出します。

バイトバディのこの増強は、ここで追跡されていますhttps://github.com/raphw/byte-buddy/issues/627

UPDATE:今後のバイトバディ1.10.0では、これはすることで可能です:

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

注釈インスタンスはにより取得することができます: AnnotationDescription.Latent.Builder.ofType(AnnotationClass.class).build()

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=231098&siteId=1