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

时间:2012-03-29 11:32:21

标签: java

我从其中一个博客

获取了以下内容

与其他人相比,JAXB变得那么慢的唯一方法就是如果他的话 为每次调用创建一个新的JAXBContext

在这里,作者提到,如果为每个新呼叫创建JAXBContext,那么它将会很慢

我正在开发基于Java EE的Web应用程序,一次可以有很多用户。

所以为了避免这种情况,如果我在静态块中创建JAXBContext调用,它只会创建一次JAXBContext吗?

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;
    }

3 个答案:

答案 0 :(得分:1)

您可以使用单件模式

例如:

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;
    }

}

因此,您可以在应用程序中通过JAXBContext方法使用单个JAXBContextFactory.getInstance()对象

The JAXBContext class is thread safe, but the Marshaller, Unmarshaller, and Validator classes are not thread safe.

答案 1 :(得分:0)

我使用这个真正的单例线程安全解决方案:

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

答案 2 :(得分:-1)

简单的答案是“是”,但是这种结构使得处理异常变得困难。我会用这种方式构造代码:

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;
        }
    }
}