2016-03-19 7 views
0

クライアントPOJOインスタンスの状態を効率的に追跡するソリューションを探しています。私たちが期待しているのは、POJOに変更が加えられるたびに、この状態がセッターを使って行われることです。 OGNLベースの視聴/イベントバスを作成しました。変更が行われた場合は、適切なOgnlChangeEventをイベントバスに送信します。コード生成を使用してPOJOの状態を追跡する方法

これまでのところ、AspectJ/cglib/object graph Diffソリューションを調べましたが、すべてがあまりにも多くのCPU時間を占めていました。現在のソリューションは、Spring MethodInterceptorに基づいており、Getterメソッドが呼び出されるたびに新しいProxyインスタンスを作成しています。

ここで、コード生成ソリューションを見ていき、Byte Buddyを見つけました。この方向は正しい方向ですか?クライアントのPOJO状態を拡張し、setterメソッドが呼び出されるまでそのOGNL接頭辞を通知する新しいClassを生成できますか?

+0

いくつかの測定でパフォーマンスの問題を詳しく説明できますか?メソッドの呼び出し回数、変更の追跡なしのメソッドの実行時間、変更の追跡による実行時間、コードの変更追跡の作業の概要 –

+0

@NándorElődFeketeに同意します。 AspectJはSpring AOPよりも遅くなければならないと考えるのは難しいです。そうであれば、AspectJは非常に効率的であるため、何か間違っていなければなりません。あなたの面を見れば、私たちが助けてくれるかもしれません。しかし、あなたがByteBuddyに満足すれば、このコメントは時代遅れです。最近私は忙しかったので、ここではあまり読んでいなかったので、ここでコメントするのはちょっと遅いです。 – kriegaex

答えて

2

バイトバディはコード生成ツールであり、もちろんそのようなソリューションを実装することは可能です。

public class MyInterceptor { 
    public static void intercept(Object value) { 
    // business logic comes here 
    } 
} 

この方法では、あなたがセッターいくつかのコードを毎回追加することができます:あなたはこのようなインターセプタを記述し

new ByteBuddy() 
    .subclass(UserPojo.class) 
    .method(ElementMatchers.isSetter()) 
    .intercept(MethodDelegation.to(MyInterceptor.class) 
      .andThen(SuperMethodCall.INSTANCE) 
    .make(); 

:セッターをインターセプトするクラスを作成するために、次のようなコードを記述します元のコードの前にトリガーされます。引数のボクシングを避けるために、すべてのプリミティブ型でインターセプトメソッドをオーバーロードすることもできます。 Byte Buddyはあなたのために何をすべきかを考え出します。

しかし、私はあなたが意味するものをperformantと混同しています。上記のコードは、私にはのようなクラスを作成するのと同じ判明:

class UserClass { 
    String value; 
    void setValue(String value) { 
    this.value = value; 
    } 
} 

class InstrumentedUserClass extends UserClass { 
    @Override 
    void setValue(String value) { 
    MyInterceptor.intercept(value); 
    super.setValue(value); 
    } 
} 

パフォーマンスは、主にあなたがinterceptメソッド内で何をすべきかのパフォーマンスの影響を受けています。

最後に、私はcglibがあなたにとってうまくいかないが、cglibの上にビルドされたSpringを使用することは理解できません。私はあなたが傍受しなければならないあなたの傍受論理にいくつかの問題があると考えます。

+0

ありがとう:-) CGLIBは私のために働いていますし、スプリングラッパーソリューションもあります。主な問題はありましたが、まだパフォーマンス:-( –

1

パフォーマンスは、あなたがメソッドインターセプタで何をするかによって異なりますが、使用するバイトコード計測フレームワークにはあまり依存しないと思います。最後に、測定するかどうかだけを知ることになります。

私はあなたのユースケースについて多くを知らないが、一般的に、私は自分自身を頼む:

  • 私は本当にどのような情報が必要ですか?
  • その情報を取得するための基本データとは何ですか?

基本データの収集とそのデータの解釈(情報)を分離する必要があります。通常、解釈に時間がかかります。基本データとは、他のデータから派生できないデータのことです。例:誕生日は基本データであり、年齢は誕生日に由来します。メソッドのインターセプタで

Iだろう

  • のみ、クラス名、メソッド名と、おそらくパラメータなどの基本的なデータを収集します。
  • この情報を何らかのワーカーキューに送信する
  • バックグラウンドワーカーに情報を生成させたり、ログに記録したり、パースしたりすることができます。

メソッド名を補間して、プロパティアクセサーかどうかを調べます。通常はを使ってIntrospectorまたは少なくとも反射APIから取得します。

+0

ありがとうRené!Ognlプレフィックスを引き続き取得するために、最も消費している部分が各getterメソッドの新しいProxyを作成していたので、バイト計測ソリューションを探しました。 –

関連する問題