1

Byte Buddy を使用してインスタンス フィールドの値を設定する方法を見つけようとしています。ドキュメントには次のように記載されています。

このような動的クラスのインスタンスでメソッドを呼び出す前に、必ずこのフィールドに値を割り当てることを忘れないでください。そうしないと、メソッド委譲によって NullPointerException が発生します。

しかし、これを行う方法に関するドキュメントや単体テストのどこにも表示されません。

私の動的クラスは次のとおりです。

new ByteBuddy().subclass(AbstractService.class)
        .name(serviceName)
        .method(ElementMatchers.named("start").and(
                ElementMatchers.takesArguments(0)))
        .intercept(
                MethodDelegation.toInstanceField(service, "consumer")
                    .filter(ElementMatchers.isAnnotatedWith(Start.class)))
        .method(ElementMatchers.named("stop").and(
                ElementMatchers.takesArguments(0)))
        .intercept(
                MethodDelegation.to(instance).filter(
                        ElementMatchers.isAnnotatedWith(Stop.class)))
        .make();

コンストラクターをインターセプト@FieldProxyして aで使用するための回答が記載された別の投稿が表示されますが、MethodDelegationその方法がわかりません。私が試したことはすべて、次のような.constructor(ElementMatchers.any()).intercept(...)結果のバリエーションになります。

java.lang.IllegalArgumentException: [] のどれもからの委譲を許可していません...

4

1 に答える 1

0

基本的に、 を使用している場合MethodDelegation.toInstanceField、Byte Buddy は生成されたクラスに指定された名前のフィールドを追加します。あなたの場合、Byte Buddy はserviceという名前のフィールドを追加しました"consumer"

このフィールドには値がないため、つまり、null割り当て前であるため、このフィールドに値を割り当てる方法を決定する必要があります。@Startそうする前にで注釈が付けられたメソッドを呼び出すと、 NullPointerException.

フィールドを割り当てる最も簡単な方法はリフレクションです。タイプセーフな代替手段は、いくつかのインターフェースを実装することです

interface SetterIFace {
  void setConsumer(MyType myType);
}

あなたのserviceタイプがClass<MyType>. その後、次を追加できます。

.implement(SetterIFace.class).intercept(FieldAccessor.ofBeanProperty())

SetterIFaceで定義した後、問題のフィールドのセッターとして実装しますMethodDelegation

于 2016-07-04T08:31:32.207 に答える