在春季启动项目中,我创建了JAXBContext bean:
@Configuration
public class MarshallerConfig {
@Bean
JAXBContext jaxbContext() throws JAXBException {
return JAXBContext.newInstance(my packages);
}
}
然后我创建包装器以使用此上下文:
@Component
public class MarshallerImpl implements Marshaler {
private final JAXBContext jaxbContext;
public MarshallerImpl(JAXBContext jaxbContext) {
this.jaxbContext = jaxbContext;
}
//murshall and unmarshal methosds imlementation
}
当我像bean创建JAXBContext
时-我知道这个JAXBContext
将是单例的。但是,现在我需要在没有@XMLRootElement
注释的情况下为marshall元素实现marhall方法。我在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());
}
}
我将JAXBContext
创建到方法JAXBContext jc = JAXBContext.newInstance(clazz);
中。
它的正确性如何?每次使用newInstance
创建对象吗?
我在此方法中稍稍看了一下,却没有发现这是一个单例。
答案 0 :(得分:0)
由于创建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);