ジャバシスト:プロキシのプロキシを作成するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/2618495

  •  26-09-2019
  •  | 
  •  

質問

javassistでプロキシを作成しています ProxyFactory. 。単一のプロキシを作成する場合は、すべて正常に機能します。

ただし、プロキシされたオブジェクトをプロキシ機構に渡すと、次のエラーが発生して失敗します。

javassist.bytecode.DuplicateMemberException:複製メソッド:com.mypackage.Bean_$$_javassist_0_$$_javassist_1 の setHandler

私はこれでプロキシを作成しています:

public Object createProxiedInstance(Object originalInstance) throws Exception {
    Class<?> originalClass = instance.getClass();
    ProxyFactory factory = new ProxyFactory();

    factory.setSuperclass(originalClass);

    factory.setHandler(new MethodHandler() {..});
    Class<T> proxyClass = factory.createClass();

    return proxyClass.newInstance();
}

では、プロキシのプロキシを作成するにはどうすればよいでしょうか?

アップデート: 実際の問題は、各プロキシが ProxyObject 定義するもの setHandler(..) 方法。したがって、2 番目のプロキシは、サブクラスでメソッドをオーバーライドするのではなく、メソッドを再定義しようとします。

役に立ちましたか?

解決

問題だった(実際には、それはCGLIBと同じだ - 私はコモンズ・プロキシを使用して、それを試してみました)私は、プロキシクラスのプロキシクラスを作成しようとはならないこと。第二プロキシは、再び元のクラスでなければなりません。したがって、次の行を追加することで問題を解決します:

if (instance instanceof ProxyObject) {
    originalClass = originalClass.getSuperclass();
}

とアドバイス - あなたは(コモンズプロキシで定義されたもののような)インターセプターのいくつかの並べ替えを使用することができた場合、代わりに複数のプロキシを使用するのでそれを行う

他のヒント

かなり遅い答えですが、それでもこれを知りたいと思うかもしれません:

Javassist プロキシはかなり単純に実装されています。上記のコードでは、Javassist は常に次のメソッドを使用してプロキシ クラスを作成します。

  1. 基本クラスのオーバーライド可能なメソッドのメソッド
  2. (a) プロキシ ハンドラーを取得する 2 つの方法 (getHandler) および (b) プロキシ ハンドラーを設定します (setHandler)

後者の 2 つのメソッドの名前は Javassist によってハードコーディングされ、次のように表されます。 ProxyObject インターフェース。ここでプロキシ クラスのプロキシ クラスを作成すると、Javassist はプロキシ クラスの作成をスケジュールします。 ProxyObjectのメソッドを 2 回実行します。最初の条件で 1 回、2 番目の条件で 1 回。

を設定することでこれを回避できます MethodFilter これは、 ProxyObjectのメソッドでは、javassist は 2 番目の条件によってのみメソッドを作成します。ただし、これは、もう設定できないことを意味します。 ProxyObject スーパークラスプロキシの場合、リフレクション経由で対応するフィールドに直接アクセスする必要はありません。したがって、あなたのアプローチはおそらく最もクリーンです。

cglib はインスタンスごとではなくクラスごとにコールバックを定義するため、cglib に関するこの問題は若干異なりますが、別の競合が発生します。

ただし、これらの欠点を抱えないプロキシ クラスを作成したい場合は、私のライブラリに興味があるかもしれません。 バイトバディ これは、特殊なケースで cglib と javassist を使用する作業にイライラした後に書きました。ランタイム コード生成を使用している場合、他のライブラリにはない柔軟性を提供できることを願っています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top