Die Frage ist ein bisschen theoretisch: Was kostet die Erstellung eines JAXB-Kontexts, Marshaller und Unmarshaller?
Ich habe festgestellt, dass mein Code davon profitieren kann, dass für alle Marshalling-Vorgänge derselbe JAXB-Kontext und möglicherweise derselbe Marshaller beibehalten wird, anstatt bei jedem Marshalling Kontext und Marshaller zu erstellen.
Was kostet die Erstellung eines JAXB-Kontexts und eines Marshallers / Unmarshallers? Ist es in Ordnung, für jede Marshalling-Operation Kontext + Marshaller zu erstellen, oder ist es besser, dies zu vermeiden?
quelle
Idealerweise sollten Sie einen Singleton
JAXBContext
und lokale Instanzen vonMarshaller
und habenUnmarshaller
.JAXBContext
Instanzen sind threadsicher, währendMarshaller
undUnmarshaller
Instanzen nicht threadsicher sind und niemals von Threads gemeinsam genutzt werden sollten.quelle
Schade, dass dies im Javadoc nicht speziell beschrieben wird. Was ich sagen kann ist, dass Spring einen globalen JAXBContext verwendet, der von Threads gemeinsam genutzt wird, während für jeden Marshalling-Vorgang ein neuer Marshaller erstellt wird. Ein Javadoc-Kommentar im Code besagt, dass JAXB-Marshaller nicht unbedingt threadsicher sind.
Das Gleiche gilt auf dieser Seite: https://javaee.github.io/jaxb-v2/doc/user-guide/ch03.html#other-miscellaneous-topics-performance-and-thread-safety .
Ich würde vermuten, dass das Erstellen eines JAXBContext eine kostspielige Operation ist, da Klassen und Pakete nach Anmerkungen durchsucht werden müssen. Aber es zu messen ist der beste Weg, es zu wissen.
quelle
JAXB 2.2 ( JSR-222 ) hat in Abschnitt "4.2 JAXBContext" Folgendes zu sagen:
Leider erhebt die Spezifikation keinen Anspruch auf Gewindesicherheit von
Unmarshaller
undMarshaller
. Es ist also am besten anzunehmen, dass dies nicht der Fall ist.quelle
Ich habe dieses Problem gelöst mit:
quelle
Noch besser!! Erstellen Sie den Kontext basierend auf der guten Lösung aus dem obigen Beitrag nur einmal im Konstruktor und speichern Sie ihn anstelle der Klasse.
Ersetzen Sie die Leitung:
mit diesem:
Und der Hauptkonstruktor mit diesem:
Im getMarshaller / getUnmarshaller können Sie diese Zeile entfernen:
Diese Verbesserung führt in meinem Fall dazu, dass die Verarbeitungszeiten von 60 bis 70 ms auf nur 5 bis 10 ms sinken
quelle
Normalerweise löse ich solche Probleme mit einem
ThreadLocal
Klassenmuster. Da Sie für jede Klasse einen anderen Marshaller benötigen, können Sie ihn mit einemsingleton
Kartenmuster kombinieren .Um Ihnen 15 Minuten Arbeit zu sparen. Hier folgt meine Implementierung einer thread-sicheren Factory für Jaxb Marshallers und Unmarshallers.
Sie können wie folgt auf die Instanzen zugreifen ...
Und der Code, den Sie benötigen, ist eine kleine Jaxb-Klasse, die wie folgt aussieht:
quelle