Proxy Design Patternの場合、JDK の Dynamic ProxyとCGLibなどのサードパーティの動的コード生成 API の違いは何ですか?
両方のアプローチを使用することの違いは何ですか?
Proxy Design Patternの場合、JDK の Dynamic ProxyとCGLibなどのサードパーティの動的コード生成 API の違いは何ですか?
両方のアプローチを使用することの違いは何ですか?
JDK 動的プロキシは、インターフェイスによってのみプロキシできます (したがって、ターゲット クラスはインターフェイスを実装する必要があり、それはプロキシ クラスによっても実装されます)。
CGLIB (および javassist) は、サブクラス化によってプロキシを作成できます。このシナリオでは、プロキシはターゲット クラスのサブクラスになります。インターフェイスは必要ありません。
したがって、Java 動的プロキシはプロキシできます: public class Foo implements iFoo
CGLIB はプロキシできます:public class Foo
編集:
javassist と CGLIB はサブクラス化によってプロキシを使用するため、これに依存するフレームワークを使用する場合、final メソッドを宣言したり、クラスを final にしたりできないのはこのためです。これにより、これらのライブラリがクラスをサブクラス化し、メソッドをオーバーライドすることができなくなります。
機能の違い
JDK プロキシを使用すると、サブクラス化中に任意のインターフェイス セットを実装できますObject
。任意のインターフェイス メソッドに加えObject::hashCode
てがObject::equals
にObject::toString
転送されますInvocationHandler
。さらに、標準ライブラリ インターフェイスjava.lang.reflect.Proxy
が実装されています。
cglib を使用すると、非最終クラスをサブクラス化しながら、任意のインターフェイス セットを実装できます。また、メソッドはオプションでオーバーライドできます。つまり、すべての非抽象メソッドをインターセプトする必要はありません。さらに、メソッドを実装するさまざまな方法があります。(別のパッケージで) クラスも提供しますが、InvocationHandler
より高度なインターセプターを使用してスーパー メソッドを呼び出すこともできますMethodInterceptor
。さらに、cglib は のような特殊なインターセプトによってパフォーマンスを向上させることができFixedValue
ます。cglib のさまざまなインターセプターの概要を書いたことがあります。
パフォーマンスの違い
JDK プロキシは、1 つのインターセプション ディスパッチャーであるInvocationHandler
. これには、常にインライン化できるとは限らない実装への仮想メソッド ディスパッチが必要です。Cglib を使用すると、パフォーマンスを向上させる特殊なバイト コードを作成できます。18 のスタブ メソッドを使用してインターフェイスを実装する場合の比較を次に示します。
cglib JDK proxy
creation 804.000 (1.899) 973.650 (1.624)
invocation 0.002 (0.000) 0.005 (0.000)
時間はナノ秒単位で示され、標準偏差が中括弧で囲まれています。ベンチマークの詳細については、Byte Buddy のチュートリアルを参照してください。ここで、Byte Buddy は cglib のより最新の代替手段です。また、cglib はもはや活発に開発されていないことに注意してください。