178

Proxy Design Patternの場合、JDK の Dynamic ProxyとCGLibなどのサードパーティの動的コード生成 API の違いは何ですか?

両方のアプローチを使用することの違いは何ですか?

4

4 に答える 4

214

JDK 動的プロキシは、インターフェイスによってのみプロキシできます (したがって、ターゲット クラスはインターフェイスを実装する必要があり、それはプロキシ クラスによっても実装されます)。

CGLIB (および javassist) は、サブクラス化によってプロキシを作成できます。このシナリオでは、プロキシはターゲット クラスのサブクラスになります。インターフェイスは必要ありません。

したがって、Java 動的プロキシはプロキシできます: public class Foo implements iFooCGLIB はプロキシできます:public class Foo

編集:

javassist と CGLIB はサブクラス化によってプロキシを使用するため、これに依存するフレームワークを使用する場合、final メソッドを宣言したり、クラスを final にしたりできないのはこのためです。これにより、これらのライブラリがクラスをサブクラス化し、メソッドをオーバーライドすることができなくなります。

于 2012-05-19T10:07:39.363 に答える
67

機能の違い

  • JDK プロキシを使用すると、サブクラス化中に任意のインターフェイス セットを実装できますObject。任意のインターフェイス メソッドに加えObject::hashCodeてがObject::equalsObject::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 はもはや活発に開発されていないことに注意してください。

于 2014-07-05T17:28:14.117 に答える