1

In spring boot project I create JAXBContext bean:

@Configuration
public class MarshallerConfig {

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

And I create Wrapper for use this context:

@Component
public class MarshallerImpl implements Marshaler {

    private final JAXBContext jaxbContext;

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

     //murshall and unmarshal methosds imlementation
    }

When I create JAXBContext like bean - I know that this JAXBContext will be singleton. But Now I need implement marhall method for marshall element without @XMLRootElement annotation. I Implement it like in this article

@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());
    }
}

I create JAXBContext into method JAXBContext jc = JAXBContext.newInstance(clazz);.

How correct is it? every time create an object using newInstance?

I looked a little inside this method and did not see that it was a singleton.

ip696
  • 6,574
  • 12
  • 65
  • 128
  • 1
    Don't do it. Have a look at [How can I improve JAXB performance?](https://stackoverflow.com/questions/18607318/how-can-i-improve-jaxb-performance) – Thomas Fritsch Oct 24 '18 at 08:46
  • @ThomasFritsch Yes. I ask about it. But then I have a problem. how do i convert an object without `@XMLRootElement` annotation? – ip696 Oct 24 '18 at 08:59
  • 1
    You can also try to reuse the `JAXBContext`s in that case. May be by caching them in a `static Map`. – Thomas Fritsch Oct 24 '18 at 09:29

1 Answers1

0

Because creating a JAXBContext is very time-consuming, you should avoid it as much as possible.

You can achieve this by caching them in a 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;
}

Finally, in your marshalToStringWithoutRoot method you can replace

JAXBContext jc = JAXBContext.newInstance(clazz);

by

JAXBContext jc = getJAXBContextForRoot(clazz);
Thomas Fritsch
  • 9,639
  • 33
  • 37
  • 49