将资源创建调用放入静态块中,将使其仅为整个应用程序创建一次



我从一个博客中截取了以下行

与其他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;
        }
    }
}

相关内容

最新更新