在spring项目中,我创建了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方法。我在这个文章中实现了它
@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
**?**创建对象时
我在这个方法里面看了一下,没有发现它是单例的。
发布于 2018-10-24 01:53:15
因为创建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);
https://stackoverflow.com/questions/52964044
复制