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
fehljavassist.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.
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.
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:
getHandler
) zu erhalten und (b) einen Proxy-Handler ( setHandler
) 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.