2009-06-16 5 views
3

私はProxy usage pageに掲載されたSunのコードを使用しようとしましたが、DebugProxyを使用してどのメソッドが呼び出されたかを印刷しようとしました。物事は、私はプロキシを作成しているオブジェクトは、引数を持つ必要があります。私は、コンストラクタの引数でプロキシを作成しようとすると、私は次のエラーが表示されます引数を取るコンストラクタでどのように動的プロキシを使用できますか?

Exception in thread "main" java.lang.ClassCastException: $Proxy0 cannot be cast to myPackage.myClass

私はこのようなプロキシを作成:


MyClass mc = (MyClass) DebugProxy.newInstance(new MyClass(props)); 

はどうやってプロキシインスタンスを作成することができ、かつそれでも正しいコンストラクタを呼び出しますか?

答えて

4

JDKで生成されたプロキシは、プロキシしているオブジェクトと同じクラスタイプではありません。代わりに、ターゲットオブジェクトの同じインタフェースを実装します。これらのインターフェイスタイプのいずれかにキャストする必要があります。

リンク先のページの例を見ると、FooImplではなくFooにキャストされています。

+0

はい。これは吸う:)。私はDynamicProxyがこれを行う簡単な方法であることを望んでいました。 – Geo

+1

この種類のプロキシは常にインターフェイスベースですが、他のプロキシ生成ライブラリはクラスの種類を直接プロキシすることができます。たとえば、CGLIBでこれを行うことができます。また、SpringのProxyFactoryを介してCGLIBプロキシを使用する場合は、面白く簡単です。 SpringのProxyFactoryは、JDKプロキシまたはCGLIBプロキシのいずれかを生成することができるので、これは有用な抽象化です。 – skaffman

2

あなたのクラスはテストしようとしているインターフェースを実装していますか?プロキシクラスは、インターフェイスのメソッドのみを実装します。クラスの各メソッドの前/後(メトリックやデバッグ用)に印刷する場合は、Aspect oriented programming(AOP)を使用することをお勧めします。私は自分でそれをやったことはありませんが、私はAspectJあなたが欲しいと聞いています。

public interface SomeInterface { 
    public void someMethod(); 
} 

public MyClass implements SomeInterface { 
... 
} 

// DebugProxy doesn't return your class, but a class which implements all of the interfaces 
// you class implements 
SomeInterface mc = (SomeInterface) DebugProxy.newInstance(new MyClass(props)); 
2

プロキシを作成する場合は、実装するインターフェイスを提供する必要があります。具体的なクラスではありません。

インターフェイスにはコンストラクタが記述されていないので、やりたいことはすぐには実行できません。