Frage

Ich Proxies mit Javassist ProxyFactory zu schaffen. Bei Verwendung eines einzelnen Proxy-Erstellung alles funktioniert gut.

Allerdings, wenn ich ein Proxy-Objekt an den Proxy-Mechanismus passiere, schlägt es mit

  

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

Ich erstelle die Proxys mit diesem:

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();
}

So, wie erstelle ich Proxies von Proxies?

Update: Die eigentlichen Probleme ist, dass jeder Proxy implementiert das ProxyObject die setHandler(..) Methode definiert. So ist der zweite Proxy versucht, das Verfahren neu zu definieren, anstatt es in der Unterklasse überschreibt.

War es hilfreich?

Lösung

Das Problem war (tatsächlich, es ist das gleiche mit CGLIB - Ich habe versucht, es commons-Proxy), dass ich nicht eine Proxy-Klasse der Proxy-Klasse zu erstellen versuchen. Der zweite Proxy sollte wieder die ursprünglichen Klasse sein. So fügen Sie folgende Zeile löst das Problem:

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

Und ein Rat - wenn Sie irgendeine Art von Abfangraketen (wie die in commons-Proxy definiert sind) verwenden können, tun Sie es stattdessen mehrere Proxys verwenden

.

Andere Tipps

Es ist ein ziemlich spät Antwort, aber man könnte noch zu wissen, interessieren:

Javassist Proxies sind eher blauäugig umgesetzt. In Ihrem obigen Code Javassist wird immer eine Proxy-Klasse mit den folgenden Methoden erstellen:

  1. Ein Verfahren für jede überschreibbare Methode der Basisklasse
  2. Zwei Methoden, um (a) erhält einen Proxy-Handler (getHandler) und (b) setzt einen Proxy-Handler (setHandler)

Die Namen der beiden letztgenannten Methoden werden von Javassist fest einprogrammiert und durch die ProxyObject Schnittstelle dargestellt. Wenn Sie jetzt eine Proxy-Klasse eines Proxy-Klasse zu erstellen, würde Javassist zweimal die Schaffung ProxyObject Methoden planen. Sobald durch den ersten Zustand und einmal durch den zweiten Zustand.

Sie können dies vermeiden, indem ein MethodFilter Einstellung, die angibt, die ProxyObject Methoden so nicht außer Kraft zu setzen, dass Javassist nur die Methoden, die von der zweiten Bedingung schaffen würde. Dies würde jedoch bedeuten, dass Sie ohne direkten Zugriff auf das entsprechende Feld über Reflexion nicht mehr ProxyObject für das Super-Klasse-Proxy einstellen könnten. Daher Ihr Ansatz ist wahrscheinlich die sauberste.

cglib definieren Rückrufe pro Klasse und nicht pro Instanz so, dass dieses Problem mit cglib etwas anders ist, führt aber zu einem anderen Konflikt.

Wenn Sie jedoch Proxy-Klassen erstellen möchten, die diese Nachteile nicht leiden, könnten Sie in meiner Bibliothek interessiert sein Byte Buddy , die ich schrieb, nachdem frustrierte arbeiten mit cglib und Javassist bekommen, wenn in Eckfällen arbeiten. Wenn Sie mit Runtime-Code Generation arbeiten hoffe ich, dass es eine gewisse Flexibilität bieten Ihnen helfen kann, dass die anderen Bibliotheken fehlen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top