我从一个博客中截取了以下行
与其他JAXB相比,JAXB的速度会那么慢的唯一方法是为每个调用创建一个新的JAXBContext
这里作者提到,如果为每个新调用创建JAXBContext,那么会很慢
我正在开发一个基于Java EE的web应用程序,在这个应用程序中,他们一次可以有很多用户。
因此,为了避免这种情况,如果我将创建JAXBContext调用放在一个静态块中,它会只创建JAXBCntext一次吗?
public class MessageParser {
private static JAXBContext jaxbContext = null;
static {
try {
jaxbContext = JAXBContext.newInstance(XML.class.getPackage().getName());
}
catch (Exception x) {
}
}
public static Message parse(String requestStr) throws Exception {
Unmarshaller um = jaxbContext.createUnmarshaller();
// Does Some processing and returns the message
return message;
}
您可以使用单例模式
例如:
public class JAXBContextFactory {
private static JAXBContext jaxbContext;
public static final JAXBContext getInstance() throws JAXBException {
if(jaxbContext == null) {
jaxbContext = JAXBContext.newInstance(XML.class.getPackage().getName());
}
return jaxbContext;
}
}
然后上你的课:
public class MessageParser {
public static Message parse(String requestStr) throws Exception {
Unmarshaller um = JAXBContextFactory.getInstance().createUnmarshaller();
// Does Some processing and returns the message
return message;
}
}
因此,您可以在应用中通过JAXBContextFactory.getInstance()
方法使用单个JAXBContext
对象
JAXBContext类是线程安全的,但Marshaller、Unmarshaller和Validator类不是线程安全的。
我使用这个真正的单例线程安全解决方案:
public class JAXBContextBeanName {
private static JAXBContextBeanName instance;
private static JAXBContext context;
public JAXBContextBeanName() {
}
public static synchronized JAXBContextBeanName getInstance() {
if(instance == null) {
instance = new JAXBContextBeanName();
}
return instance;
}
public synchronized JAXBContext getContext() throws Exception {
try {
if (context == null) {
context = JAXBContext.newInstance(ObjectFactory.class);
}
} catch (JAXBException e) {
}
return context;
}
}
然后将其与以下内容一起用于封送:
JAXBContextBeanName singleton = JAXBContextBeanName.getInstance();
JAXBContext jaxbContext = singleton.getContext();
Marshaller marshaller = jaxbContext.createMarshaller();
synchronized (marshaller) {
marshaller.marshal(beanObject, document);
}
和用于解组:
JAXBContextBeanName singleton = JAXBContextBeanName.getInstance();
JAXBContext jaxbContext = singleton.getContext();
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
synchronized(unmarshaller) {
asd = (ASD) unmarshaller.unmarshal(document));
}
简单的答案是"是",但这种结构使处理异常变得困难。我会这样构建代码:
public class MessageParser {
private static JAXBContext jc = null;
public static Message parse(String requestStr) throws Exception {
if(jc == null) {
try {
jaxbContext = JAXBContext.newInstance(XML.class.getPackage().getName());
}
catch (Exception x) {
//now you are in the context of the method so can deal with the exception properly
//or just throw it to let the caller deal with it.
}
}
if(jc != null) {
Unmarshaller um = jaxbContext.createUnmarshaller();
// Does Some processing and returns the message
return message;
}
else {
return null;
}
}
}