Jemand, bei dem ich arbeite, bemerkte (in Stacktrace), dass wenn ich den jvm mit -javaagent: spring-instrumentation.jar starte, meine JAXB annotierten Klassen seltsame neue Methoden in ihnen haben, die wir nicht geschrieben haben: z.B. SomeJaxbAnnotatedClass $ JaxbAccessorM_getFields_setFields_java_util_Set.get
Bedeutet dies, dass jaxb Bytecode-Instrumentierung verwendet, wenn sie verfügbar ist? Wo kann ich mehr über diese Funktionalität lesen?
Danke, Yuval
Nur eine Ergänzung zu Skaffmans Beitrag:
Was Sie sehen (SomeJaxbAnnotatedClass $ JaxbAccessor ...) ist eine innere Klasse, die dynamisch von der JAXB-Referenzimplementierung erzeugt wird. Um Reflektionsaufwand zur Laufzeit zu vermeiden, werden Bytecode für die konkreten Implementierungen der Klasse com.sun.xml.bind.v2.runtime.reflect.Accessor
erzeugt und in den aktuellen Klassenlader durch Aufruf von ClassLoader.defineClass (String, byte [], int, int) injiziert, nachdem reflection zur Umgehung des protected verwendet wurde Zugriffsmodifikator der Methode defineClass.
Die JAXB-Referenzimplementierung instrumentiert also keinen Bytecode in dem Sinne, dass vorhandene Klassen modifiziert werden, sondern neue Klassen für eine optimierte Laufzeitleistung generiert werden.
Wenn% code_% gestartet wird, führt es eine große Anzahl von Reflektionsoperationen aus, um alle später benötigten Dateien vorab zu cachen. Dies geschieht aus Leistungsgründen. Ich bin nicht sicher, was genau es tut, aber ich würde erwarten, dass es irgendeine Art von Laufzeitklassengenerierungslogik ausführt, da das zur Laufzeit schneller ist als die rohe Reflexion.
Interessanterweise können Sie dieses Verhalten deaktivieren, indem Sie eine nicht dokumentierte Systemeigenschaft festlegen, die den Start des Kontextes auf Kosten der Laufzeitleistung verbessert.
edit: Ich sollte betonen, dass dies die Sun JAXB-Referenzimplementierung unter den Deckblättern tut, sie ist nicht Teil der JAXB-Spezifikation. Andere Implementierungen können frei tun, was sie wollen.
Als letztes habe ich überprüft, dass JAXB Reflektionen verwendet, um Klassen basierend auf dem von Ihnen bereitgestellten XML zu generieren (obwohl ich es seit einiger Zeit nicht mehr verwendet habe, so dass sie möglicherweise ihre Methodologie geändert haben).
Ich weiß, dass JiBX andererseits BCEL , um Bytecode-Instrumentierung durchzuführen. Hier ist ein Artikel darüber: Ссылка .
Wie von skaffman erwähnt, können Sie die Generierung all dieser inneren Klassen ausschalten, indem Sie die Systemeigenschaft setzen: com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.fastBoot = true
Natürlich ist es nicht dokumentiert, aber es hat sich seit Jahren nicht geändert.
Tags und Links java jaxb bytecode-manipulation