Javassist: Wie erstelle ich einen Proxy des Proxy?

9

Ich erstelle Proxys mit javassist ProxyFactory . Bei der Erstellung eines einzelnen Proxy funktioniert alles einwandfrei.

Wenn ich jedoch ein Proxy-Objekt an den Proxy-Mechanismus übergebe, schlägt es mit

fehl
  

javassist.bytecode.DuplicateMemberException: doppelte Methode: setHandler in com.mypackage.Bean _ $$ _ javassist_0 _ $$ _ javassist_1

Ich erstelle die Proxies mit diesem:

%Vor%

Also, wie erstelle ich Proxies von Proxies?

Update: Das eigentliche Problem ist, dass jeder Proxy den ProxyObject implementiert, der setHandler(..) method definiert. Der 2. Proxy versucht also, die Methode neu zu definieren, anstatt sie in der Unterklasse zu überschreiben.

    
Bozho 11.04.2010, 20:03
quelle

2 Antworten

4

Das Problem war (eigentlich ist es das gleiche mit CGLIB - ich versuchte es mit Commons-Proxy), dass ich nicht versuchen sollte, eine Proxy-Klasse der Proxy-Klasse zu erstellen. Der zweite Proxy sollte wieder der ursprünglichen Klasse angehören. Das Hinzufügen der folgenden Zeile behebt das Problem:

%Vor%

Und ein Ratschlag - wenn Sie eine Art von Interzeptoren (wie die, die in commons-proxy definiert sind) verwenden können, tun Sie es anstatt mehrere Proxies zu verwenden.

    
Bozho 12.04.2010, 21:19
quelle
1

Es ist eine ziemlich späte Antwort, aber Sie könnten immer noch daran interessiert sein, dies zu wissen:

Javassist-Proxies sind eher naiv implementiert. In Ihrem obigen Code erstellt Javassist immer eine Proxy-Klasse mit den folgenden Methoden:

  1. Eine Methode für jede überschreibbare Methode der Basisklasse
  2. Zwei Methoden, um (a) einen Proxy-Handler ( getHandler ) zu erhalten und (b) einen Proxy-Handler ( setHandler )
  3. zu setzen

Die Namen der beiden letzteren Methoden sind von Javassist fest codiert und werden durch die Schnittstelle ProxyObject dargestellt. Wenn Sie jetzt eine Proxy-Klasse einer Proxy-Klasse erstellen, plant Javaassist die Erstellung der Methoden von ProxyObject zweimal. Einmal bei der ersten Bedingung und einmal bei der zweiten Bedingung.

Sie können dies vermeiden, indem Sie eine MethodFilter setzen, die angibt, dass die Methoden von ProxyObject nicht überschrieben werden sollen, sodass javassist die Methoden nur durch die zweite Bedingung erstellt. Dies würde jedoch bedeuten, dass Sie ProxyObject nicht länger für den Superklassen-Proxy festlegen können, ohne direkt über Reflektion auf das entsprechende Feld zuzugreifen. Daher ist Ihr Ansatz wahrscheinlich der sauberste.

cglib definiert Callbacks pro Klasse und nicht pro Instanz, so dass dieses Problem mit cglib etwas anders ist, aber in einem anderen Konflikt resultiert.

Wenn Sie jedoch Proxy-Klassen erstellen möchten, die diese Mängel nicht aufweisen, könnten Sie an meiner Bibliothek Byte Buddy interessiert sein, die ich geschrieben habe nachdem ich frustriert mit cglib und javassist gearbeitet habe, wenn ich in Ecken gearbeitet habe. Wenn Sie mit der Generierung von Runtime-Code arbeiten, hoffe ich, dass es Ihnen dabei hilft, Ihnen eine gewisse Flexibilität zu bieten, die den anderen Bibliotheken fehlt.

    
Rafael Winterhalter 03.05.2014 14:33
quelle

Tags und Links