Насколько правильно создавать JAXBContext, используя newInstance () при каждом вызове метода? - PullRequest
0 голосов
/ 24 октября 2018

В весеннем загрузочном проекте я создаю JAXBContext bean:

@Configuration
public class MarshallerConfig {

    @Bean
    JAXBContext jaxbContext() throws JAXBException {
        return JAXBContext.newInstance(my packages);
    }
}

И создаю Wrapper для использования этого контекста:

@Component
public class MarshallerImpl implements Marshaler {

    private final JAXBContext jaxbContext;

    public MarshallerImpl(JAXBContext jaxbContext) {
        this.jaxbContext = jaxbContext;
    }

     //murshall and unmarshal methosds imlementation
    }

Когда я создаю JAXBContext как bean - я знаючто это JAXBContext будет синглтоном.Но теперь мне нужно реализовать метод Мархалла для элемента маршала без аннотации @XMLRootElement.Я реализую это как в этой статье

@Override
public <T> String marshalToStringWithoutRoot(T value, Class<T> clazz) {
    try {
        StringWriter stringWriter = new StringWriter();

        JAXBContext jc = JAXBContext.newInstance(clazz);
        Marshaller marshaller = jc.createMarshaller();
        // format the XML output
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);

        QName qName = new QName(value.getClass().getPackage().toString(), value.getClass().getSimpleName());
        JAXBElement<T> root = new JAXBElement<>(qName, clazz, value);

        marshaller.marshal(root, stringWriter);

        return stringWriter.toString();
    } catch (JAXBException e) {
        throw new RuntimeException(e.getMessage());
    }
}

Я создаю JAXBContext в методе JAXBContext jc = JAXBContext.newInstance(clazz);.

Насколько это правильно?каждый раз создавая объект, используя newInstance?

Я немного заглянул внутрь этого метода и не увидел, что это был синглтон.

1 Ответ

0 голосов
/ 24 октября 2018

Поскольку создание JAXBContext занимает очень много времени, вам следует избегать его как можно больше.

Этого можно добиться, кэшируя их в Map<Class<?>, JAXBContext>.

private static Map<Class<?>, JAXBContext> contextsByRootClass = new HashMap<>();

private static JAXBContext getJAXBContextForRoot(Class<?> clazz) throws JAXBException {
    JAXBContext context = contextsByRootClass.get(clazz);
    if (context == null) {
        context = JAXBContext.newInstance(clazz);
        contextsByRootClass.put(clazz, context);
    }
    return context;
}

Наконец, в вашем marshalToStringWithoutRoot методе вы можете заменить

JAXBContext jc = JAXBContext.newInstance(clazz);

на

JAXBContext jc = getJAXBContextForRoot(clazz);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...