Was ist der Unterschied zwischen dem dynamischen JDK-Proxy und CGLib?
Im Falle der Proxy-Design-PatternWas ist der Unterschied zwischen JDK Dynamischen Proxy und Dritte dynamische code-Generierung-API ' s wie CGLib?
Was ist der Unterschied zwischen den mit beiden Methoden, und Wann sollte man lieber eine über die andere?
InformationsquelleAutor der Frage KDjava | 2012-05-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
JDK Dynamische proxy können nur proxy-Schnittstelle (also Ihre Ziel-Klasse muss eine Schnittstelle implementieren, die dann auch umgesetzt durch die proxy-Klasse).
CGLIB (und javassist) kann ein Proxykonto erstellen von Unterklassen. In diesem Szenario der proxy wird zu einer Unterklasse des target-Klasse. Keine Notwendigkeit für Schnittstellen.
Also Java Dynamische proxies können proxy:
public class Foo implements iFoo
wo CGLIB können proxy:public class Foo
EDIT:
Sollte ich erwähnen, dass da javassist und CGLIB proxy verwenden, indem bilden von Unterklassen, dass dies ist der Grund, warum Sie kann nicht erklären, final-Methoden oder der Klasse-Finale bei der Verwendung von frameworks, die auf diese angewiesen sind. Das würde aufhören, mit diesen Bibliotheken zu gestatten, dass eine Unterklasse Ihrer Klasse und überschreiben Sie die Methoden.
InformationsquelleAutor der Antwort raphaëλ
Unterschiede in der Funktionalität
Den JDK-proxies erlauben die Umsetzung jeder Satz von Schnittstellen, während die Unterklassen
java.lang.reflect.Proxy
. Jede interface-Methode, plusObject::hashCode
Object::equals
undObject::toString
wird dann weitergeleitet zu einemInvocationHandler
.cglib können Sie implementieren Schnittstellen, während die Unterklassen alle non-final Klasse. Auch Methoden können überschrieben werden Optional, d.h. nicht alle nicht-abstrakten Methoden müssen abgefangen werden. Darüber hinaus gibt es verschiedene Möglichkeiten der Implementierung einer Methode. Es bietet auch eine
InvocationHandler
Klasse (in einem anderen Paket), aber es auch erlaubt das aufrufen super Methoden durch die Verwendung von mehr fortgeschrittene Abfangjäger, wie zum Beispiel eineMethodInterceptor
. Darüber hinaus cglib kann die Leistung verbessern, indem Sie spezialisierte Abhörmaßnahmen wieFixedValue
. Ich schrieb einmal eine Zusammenfassung der verschiedenen Abfangjäger für cglib.Performance-Unterschiede
JDK-proxies implementiert werden, die eher naiv mit nur einem interception-dispatcher, die
InvocationHandler
. Dies erfordert eine virtuelle Methode dispatch auf eine Umsetzung, die nicht immer inline. Cglib ermöglicht das erstellen von spezialisierten byte-code, was kann manchmal die Leistung zu verbessern. Hier sind einige Vergleiche, die für die Implementierung einer Schnittstelle mit 18 stub-Methoden:Die Zeit vermerkt ist, die in Nanosekunden mit Standardabweichung in Klammern. Sie finden weitere details auf der benchmark in Byte Buddy ' s tutorialwo Byte-Buddy ist eine moderne alternative zu cglib. Beachten Sie auch, dass cglib ist nicht mehr unter aktiver Entwicklung.
InformationsquelleAutor der Antwort Rafael Winterhalter
Dynamic proxy: Dynamische Implementierungen von Schnittstellen zur Laufzeit mit JDK Reflection-API.
Beispiel: Frühjahr verwendet dynamische proxies für Transaktionen wie folgt:
Den generierten proxy kommt auf der Oberseite der Bohnen. Es fügt transnationalen Verhalten die Bohne. Hier der proxy erzeugt dynamisch zur Laufzeit mit JDK Reflection-API.
Wenn eine Anwendung beendet wird, ist der proxy wird zerstört werden und wir werden nur noch interface und bean auf das Datei-system.
Im obigen Beispiel haben wir ein interface. Aber in den meisten von der Implementierung der Schnittstelle ist nicht das beste. So bean nicht implementieren eine Schnittstelle, in diesem Fall haben wir verwendet-Vererbung:
Zur Erzeugung solcher proxies, Spring nutzt eine Drittanbieter-Bibliothek genannt CGLib.
CGLib (Code Generation Libtemporären) baut auf ASMdies ist hauptsächlich die Erzeugung der proxy-Erweiterung bean und fügt bean Verhalten in der proxy-Methoden.
Beispiele für JDK Dynamische proxy-und CGLib
Frühling ref
InformationsquelleAutor der Antwort Premraj
Von der Spring-Dokumentation :
Spring AOP nutzt entweder das JDK dynamische proxies oder CGLIB erstellen Sie den proxy für ein bestimmtes Zielobjekt. (JDK dynamische proxies werden bevorzugt, Wann immer Sie eine Wahl haben).
Wenn das Ziel-Objekt Proxy implementiert mindestens eine Schnittstelle dann ein JDK dynamische proxy verwendet wird. Alle implementierten Schnittstellen, die von der Ziel-Typ umgeleitet. Wenn das target-Objekt nicht implementiert alle Schnittstellen, die dann einer CGLIB-proxy erstellt wird.
Wenn Sie erzwingen möchten, dass die Benutzung der CGLIB-proxying (zum Beispiel, um einen proxy für jede Methode definiert, die für das Ziel-Objekt, nicht nur diejenigen, implementiert seine Schnittstellen) können Sie das tun. Es gibt jedoch einige Aspekte zu berücksichtigen:
final-Methoden können nicht empfohlen werden, da Sie nicht überschrieben werden.
Müssen Sie die CGLIB 2-Binärdateien auf Ihrem classpath, in der Erwägung, dass dynamische proxies vorhanden sind mit dem JDK. Frühjahr wird Sie automatisch warnen, wenn er Sie braucht CGLIB und die CGLIB-Bibliothek Klassen sind, nicht auf dem classpath.
Den Konstruktor des Proxy-Objekt zweimal aufgerufen werden. Dies ist eine Natürliche Folge der CGLIB-proxy-Modell, wobei eine Unterklasse erzeugt für jedes Proxy-Objekt. Für jede Proxy-Instanz werden zwei Objekte erzeugt: die eigentliche Proxy-Objekt und eine Instanz der Unterklasse implementiert die Beratung. Dieses Verhalten wird nicht ausgestellt, wenn mit dem JDK-proxies. In der Regel, Aufruf des Konstruktors der Proxy-Typ doppelt, ist kein Thema, da es in der Regel nur Aufgaben, die stattfinden und keine wirkliche Logik implementiert, die im Konstruktor.
InformationsquelleAutor der Antwort Taras Melnyk