Gibt es Alternativen zu cglib?
Nur aus Neugier, gibt es (stabile) open-source-Projekte für die Laufzeit-java-code-Generierung eine andere als cglib? Und warum sollte ich Sie benutzen?
InformationsquelleAutor der Frage Mauli | 2010-02-14
Du musst angemeldet sein, um einen Kommentar abzugeben.
ASM java-asm
CGLIB und fast alle anderen Bibliotheken werden gebaut auf der Oberseite des ASM, die selbst agiert auf einem sehr niedrigen Niveau. Dies ist ein show-stopper für die meisten Menschen wie Sie haben zu verstehen, die byte-code und ein wenig von der JVMS um es richtig zu nutzen. Aber mastering ASM ist sicherlich sehr interessant. Beachten Sie jedoch, dass, während es ist ein große ASM 4-Anleitungin einigen teilen der API in der javadoc-Dokumentation kann sehr prägnant, wenn es überhaupt vorhanden ist, aber es wird verbessert. Es verfolgt die JVM-Versionen zur Unterstützung der neuen Funktionen.
Aber, wenn Sie die volle Kontrolle, ASM ist Ihre Waffe der Wahl.
Diesem Projekt sieht regelmäßige updates ; zum Zeitpunkt dieses edit version 5.0.4 wurde veröffentlicht am 15 Mai 2015.
Byte Buddy byte-buddy
Byte Buddy ist eine eher neue Bibliothek bietet aber alle Funktionen, die CGLIB oder Javassist bietet und vieles mehr. Byte Buddy kann vollständig angepasst werden nach unten, um die byte-code-Ebene und kommt mit einem ausdrucksstarken domain-spezifische Sprache, die ermöglicht, dass sehr lesbaren code.
Typsichere callbacks
Annotation-driven (flexibel)
Als agent
Den wichtigsten Nachteil vielleicht, würde der API ist ein wenig ausführlich für einen Anfänger, aber es ist konzipiert als ein opt-in-API geformt wie ein proxy-Generierung DSL ; es gibt keine Magie oder fragwürdigen Vorgaben. Wenn die Manipulation von byte-code ist es wohl die meisten und sicher die vernünftigste Wahl. Auch mit mehreren Beispielen und einer großen tutorial dies ist nicht ein echtes Problem.
Im Oktober 2015 diese Projekte erhielt die Oracle Duke ' s choice award. Dieses mal ist es einfach nur erreicht die 1.0.0 Meilensteindas ist schon eine Leistung.
Beachten Sie, dass mockito ersetzt hat CGLIB von Byte-Buddy in der version 2.1.0.
Javassist javassist
In der javadoc von Javassist ist viel besser als die, dass der CGLIB. Die class engineering API OK ist, aber Javassist ist auch nicht perfekt. Insbesondere die
ProxyFactory
was ist das äquivalent der CGLIB istEnhancer
leiden einige Nachteile auch, um nur einige zu nennen :ClassloaderProvider
ist ein statisches Feld statt, dann gilt für alle Instanzen innerhalb der selben classloaderProxyFactory
.Auf die Aspekt-orientierte Seite, kann man einfügen von code in einem proxy, aber dieser Ansatz in Javassist ist begrenzt und eine bit-Fehler-anfällig :
Auch Javassist ist, erkannt zu werden, langsamer als Cglib. Dies ist vor allem auf seinen Ansatz der reading class-Dateien zu Lesen, anstatt die geladenen Klassen wie CGLIB tut. Und die Umsetzung selbst ist schwer zu Lesen, um fair zu sein, wenn man benötigt, um änderungen in der Javassist-code gibt es viele Chancen, etwas kaputt zu machen.
Javassist litt Inaktivität als gut, Ihre Bewegung zu github circa 2013 zu haben scheinen, die sich als sinnvoll erwiesen, da es zeigt, regelmäßige commits und pull-requests aus der community.
Diese Einschränkungen stehen noch in der version 3.17.1. Version wurde, stieß auf version 3.20.0, doch scheint es Javassist kann habe noch Probleme mit Java-8-Unterstützung.
JiteScript
JiteScript scheint wie ein neues Stück schön die Gestaltung bis DSL für ASM, dies ist auf der Grundlage der neuesten ASM-release (4.0). Der code sauber aussieht.
Aber das Projekt ist noch in seinen frühen Alter, so API /Verhalten ändern können, plus die Dokumentation ist schrecklich. Und updates Mangelware, wenn nicht aufgegeben.
Proxetta jodd
Dies ist eine eher neue tool, aber es bietet die mit Abstand beste menschlichen API. Es ermöglicht für verschiedene Arten von proxies, wie Unterklasse proxies (cglib-Ansatz) oder Weben oder delegation.
Obwohl, diesmal ist es eher selten, keine Informationen vorhanden, ob es gut funktioniert. Es gibt so viele Ecke Fall zu behandeln, wenn der Umgang mit bytecode.
AspectJ aspectj
AspectJ ist ein sehr mächtiges Werkzeug für Aspekt-orientierte Programmierung (nur). AspectJ manipuliert-byte-code, um seine Ziele zu erreichen, so dass Sie in der Lage sein könnten, Ihre Ziele zu erreichen. Dies erfordert jedoch, dass die Bearbeitung zur compile-Zeit; Frühling bieten das Weben zur Ladezeit über einen Agenten, der seit version 2.54.1.x.
CGLIB cglib
Ein Wort über die CGLIB, die aktualisiert wurde, nachdem diese Frage gestellt wurde.
CGLIB ist Recht schnell, es ist einer der Hauptgründe, warum es immer noch um, zusammen mit der Tatsache, dass CGLIB funktionierte fast besser als alle alternativen, bis jetzt (2014-2015).
Generell Bibliotheken, die es ermöglichen, das umschreiben der Klassen zur Laufzeit zu vermeiden, laden Sie alle Arten, bevor die jeweilige Klasse geschrieben werden. Daher können Sie nicht machen Gebrauch von der Java reflection API, die erfordert, dass jede Art verwendet, in der Reflexion ist geladen. Stattdessen haben Sie Lesen der Klasse-Dateien via IO (das ist ein Leistungs-Schutzschalter). Dies macht zum Beispiel Javassist oder Proxetta deutlich langsamer als der Cglib, die liest einfach die Methoden über die reflection-API und überschreibt Sie.
Jedoch CGLIB ist nicht mehr unter aktiver Entwicklung. Es waren die letzten Versionen, aber diese änderungen waren gesehen als unbedeutend, von vielen und die meisten Menschen haben nie das update auf die version 3 da CGLIB führte einige schwere bugs in den letzten Versionen, was nicht wirklich Vertrauen aufbauen.in der Version 3.1 behoben, eine Menge, die Nöte der version 3.0 (seit version 4.0.3 für das Spring-framework neu verpackt version 3.1).Auch, die CGLIB-source-code ist eher schlechte Qualitätdass wir nicht sehen, neue Entwickler-Beitritt der CGLIB-Projekt. Für einen Eindruck von CGLIB ist Geschäftigkeit, sehen Ihre Mailingliste.
Beachten Sie, dass nach einer proposition auf dem guice-mailing-ListeCGLIB ist jetzt verfügbar auf github zu ermöglichen, die Gemeinschaft besser helfen, das Projekt, es scheint zu funktionieren (mehrere commits und pull-requests, ci, aktualisiert maven), doch die meisten Bedenken bleiben trotzdem bestehen.
In dieser Zeit dort arbeiten, version 3.2.0, und Sie sind, konzentrieren sich die Anstrengungen auf Java 8, aber bisher sind die Benutzer, die wollen, dass java-8-Unterstützung verwenden tricks zur build-Zeit. Aber der Fortschritt ist sehr langsam.
Und CGLIB ist noch bekannt, geplagt zu sein für PermGen-Speicher-Leck. Aber auch andere Projekte, die vielleicht nicht in der Schlacht getestet für so viele Jahre.
Compile-Zeit, annotation-Verarbeitung annotation-processing
Dieser ist nicht Laufzeit natürlich, aber ist ein wichtiger Teil des ökosystems, und die meisten der code-Generierung Verwendung nicht brauchen, Laufzeit Schöpfung.
Diese Schritte mit Java 5 kamen mit den separaten Befehl-Linie Werkzeug, um Prozess-Anmerkungen :
apt
und das starten von Java 6 die annotation processing integriert, das den Java-compiler.Irgendwann mussten Sie explizit übergeben Sie den Prozessor, der nun mit der
ServiceLoader
Ansatz (fügen Sie einfach diese DateiMETA-INF/services/javax.annotation.processing.Processor
dem Glas) erkennt der compiler automatisch die annotation-Prozessor.Dieser Ansatz bei der code-Generierung hat auch Nachteile, es erfordert eine Menge Arbeit und das Verständnis der Sprache Java nicht-bytecode. Diese API ist ein wenig umständlich, und wie man plugins in den compiler muss man mit äußerster Sorgfalt, damit dieser code die am meisten belastbar und benutzerfreundliche Fehlermeldung.
Der größte Vorteil hier ist, dass es vermeidet eine weitere Abhängigkeit zur Laufzeit, können Sie vermeiden, permgen-Speicher-Leck. Und man hat die volle Kontrolle über den generierten code.
Abschluss
In Zwei tausend zwei CGLIB definiert einen neuen standard zu manipulieren bytecode mit Leichtigkeit. Viele tools und Methoden (CI, Abdeckung, TDD, etc.) wir haben heute nicht verfügbar waren, oder nicht, Reifen in dieser Zeit. CGLIB verwaltet werden, als relevant für mehr als ein Jahrzehnt ; das ist eine sehr ordentliche Leistung. Es war schnell und mit einem einfachen API zu verwenden, als die Manipulation opcodes Entfernung anspringen.
Es definiert neuen standard in Bezug auf code-Generierung, aber heutzutage ist es nicht mehr, weil die Umgebung und die Anforderungen haben sich geändert, so haben die Normen und Ziele.
Die JVM geändert und wird sich ändern, in den letzten und zukünftigen Java (7/8/9/10) Versionen (invokedynamic, Standard-Methoden, Datentypen, etc.). ASM aktualisiert seine API und Interna regelmäßig zu Folgen, diese änderungen aber CGLIB und andere haben noch, Sie zu benutzen.
Während annotation Verarbeitung ist immer Traktion, es ist nicht so flexibel, da die Laufzeit-Generierung.
Ab 2015 Byte Buddy — zwar eher neu in der Szene — Angebot das überzeugendste Verkauf Punkte für die Laufzeit-Generierung. Eine anständige update-rate und der Autor hat eine intime Kenntnis der Java-byte-code-Interna.
InformationsquelleAutor der Antwort Brice
Javassist.
Wenn Sie brauchen, um machen, proxies, werfen Sie einen Blick auf commons-proxy - er verwendet sowohl CGLIB und Javassit.
InformationsquelleAutor der Antwort Bozho
Ich bevorzuge raw ASMich glaube, Sie wird von cglib sowieso. Es ist low-level, aber die Dokumentation ist brilliantund wenn Sie sich einmal daran gewöhnt werden Sie Fliegen.
Zur Beantwortung Ihrer zweiten Frage, die Sie verwenden sollten, code-Generierung, wenn Ihr Spiegelbild und dynamische proxies beginnen zu fühlen, ein bisschen zusammengeschustert, und Sie müssen eine solide Lösung. In der Vergangenheit habe ich auch noch ein code-Generierung Schritt in den build-Prozess von Eclipse, wodurch mir die compile-Zeit-Berichterstattung von nichts und alles.
InformationsquelleAutor der Antwort CurtainDog
Ich denke, dass es mehr Sinn Javassist statt cglib. E. g. javasist perfekt funktioniert mit signierten jars im Gegensatz zu cglib. Außerdem, so großartig wie Hibernate Projekt beschlossen, zu stoppen mithilfe von cglib zu Gunsten von Javassist.
InformationsquelleAutor der Antwort FoxyBOA
Proxetta ist ein weiterer weniger bekannte java-proxy-framework.
InformationsquelleAutor der Antwort cdp4j
CGLIB wurde entworfen und implementiert, die vor mehr als zehn Jahren in der AOP-und ORM-ära.
Aktuell sehe ich keine Gründe, es zu benutzen und ich nicht, dass dieser Bibliothek mehr (außer bug-fixes für mein legacy-Anwendungen ).
Eigentlich alle von CGLIB use-cases, die ich je sah, sind anti-patterns in der modernen Programmierung.
Es sollte trivial zu implementieren die gleiche Funktionalität über jede JVM-scripting-Sprache (z.B. groovy.
InformationsquelleAutor der Antwort jbaliuka