2009-06-16 5 views
3

Ich habe versucht, den Code Sun auf ihre Proxy usage page geschrieben, und ich habe versucht, den DebugProxy zu verwenden, welche Methode aufgerufen wird. Die Sache ist, das Objekt, für das ich einen Proxy erstelle, muss ein Argument haben. Wenn ich versuche, den Proxy mit einem Argument an den Konstruktor zu erstellen, erhalte ich folgende Fehlermeldung:Wie kann ich einen dynamischen Proxy für Konstruktoren verwenden, die Argumente verwenden?

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

ich den Proxy wie folgt erstellt:


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

Wie kann ich einen Proxy-Instanz erstellen, und Rufen Sie immer noch den richtigen Konstruktor an?

Antwort

4

Der von JDK generierte Proxy gehört nicht zum selben Klassentyp wie das Objekt, das Sie als Proxy verwenden. Stattdessen implementiert es die gleichen Schnittstellen des Zielobjekts. Sie müssen auf einen dieser Schnittstellentypen umstellen.

Wenn Sie sich das Beispiel auf der Seite anschauen, auf die Sie verlinkt haben, handelt es sich um Foo, nicht um FooImpl.

+0

ja. das ist scheiße :). Ich hatte gehofft, DynamicProxy wäre eine schnelle Möglichkeit, dies zu tun. – Geo

+1

Diese Art von Proxy ist immer schnittstellenbasiert, aber andere Proxy-Generierungsbibliotheken können Ihre Klassentypen direkt übernehmen. Zum Beispiel kann CGLIB dies tun, und wenn Sie CGLIB-Proxying über Spring's ProxyFactory verwenden, ist es urkomisch einfach. Die ProxyFactory von Spring kann entweder JDK-Proxies oder CGLIB-Proxies generieren, was eine nützliche Abstraktion darstellt. – skaffman

2

Implementiert Ihre Klasse eine Schnittstelle, die Sie testen möchten? Proxy-Klassen implementieren nur Methoden von einer Schnittstelle. Wenn Sie vor/nach jeder Methode einer Klasse (sei es für Metriken oder Debugging) drucken wollen, würde ich vorschlagen, Aspect-orientierte Programmierung (AOP) zu verwenden. Ich habe es nie selbst gemacht, aber ich höre AspectJ ist was du willst.

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

Wenn Sie einen Proxy erstellen möchten, müssen Sie eine zu implementierende Schnittstelle bereitstellen. Keine konkrete Klasse.

Schnittstellen beschreiben nicht Konstruktoren, also was Sie tun möchten, ist nicht sofort durchführbar.