Вопрос немного теоретический, какова стоимость создания JAXB context, marshaller и unmarshaller?
Я обнаружил, что моему коду может быть полезно сохранить один и тот же контекст JAXB и, возможно, один и тот же маршаллер для всех операций маршалинга, а не создавать контекст и маршаллер для каждого маршалинга.
Итак, какова стоимость создания контекста JAXB и маршаллера / демаршаллера? Можно ли создавать контекст + маршаллер для каждой операции маршалинга или лучше этого избегать?
источник
В идеале у вас должны быть одноэлементные
JAXBContext
и локальные экземплярыMarshaller
иUnmarshaller
.JAXBContext
экземпляры являются потокобезопасными,Marshaller
аUnmarshaller
экземпляры не являются потокобезопасными и никогда не должны совместно использоваться между потоками.источник
Жалко, что это не описано конкретно в javadoc. Что я могу сказать, так это то, что Spring использует глобальный JAXBContext, совместно используемый между потоками, тогда как он создает новый маршаллер для каждой операции маршаллинга с комментарием javadoc в коде, говорящем, что маршаллеры JAXB не обязательно потокобезопасны.
То же самое сказано на этой странице: https://javaee.github.io/jaxb-v2/doc/user-guide/ch03.html#other-miscellaneous-topics-performance-and-thread-safety .
Я предполагаю, что создание JAXBContext - дорогостоящая операция, поскольку она включает сканирование классов и пакетов на предмет аннотаций. Но лучший способ узнать это - измерить.
источник
В JAXB 2.2 ( JSR-222 ) в разделе «4.2 JAXBContext» говорится следующее:
К сожалению, спецификация не делает никаких заявлений относительно поточной безопасности
Unmarshaller
иMarshaller
. Так что лучше предположить, что это не так.источник
Я решил эту проблему с помощью:
источник
Даже лучше!! Основываясь на хорошем решении из сообщения выше, создайте контекст только один раз в конструкторе и сохраните его вместо класса.
Заменить строку:
с этим:
И главный конструктор с этим:
поэтому в getMarshaller / getUnmarshaller вы можете удалить эту строку:
В моем случае это улучшение сокращает время обработки с 60 ~ 70 мс до всего 5 ~ 10 мс.
источник
Обычно я решаю подобные проблемы с помощью
ThreadLocal
шаблона класса. Учитывая тот факт, что вам нужен другой маршаллер для каждого класса, вы можете комбинировать его сsingleton
шаблоном -map.Чтобы сэкономить вам 15 минут работы. Здесь следует моя реализация поточно-ориентированной Factory для Jaxb Marshallers и Unmarshallers.
Это позволяет вам получить доступ к экземплярам следующим образом ...
И код, который вам понадобится, - это небольшой класс Jaxb, который выглядит следующим образом:
источник