将昂贵的资源创建放在静态块中?

时间:2012-06-13 15:08:47

标签: java jaxb

我正在使用JAXB 2.0版本。为此,我按以下方式创建JAXBContext对象:

package com;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;

public class JAXBContextFactory {

    public static JAXBContext createJAXBContext() throws JAXBException {
        JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);

        return jaxbContext;
    }

}

基本上,因为创建JAXBContext非常昂贵,所以我想为整个应用程序创建一次JAXBContext并且只创建一次。所以我将JAXBContext代码放在静态方法下,如上所示。

现在,只要需要JAXBContextFactory.createJAXBContext();的引用,请求就会调用JAXBContex现在我的问题是,在这种情况下,JAXBContext仅创建一次,或者应用程序是否有多个JAXBContext实例?

5 个答案:

答案 0 :(得分:5)

每次调用此方法时,您的应用程序都会有一个JAXBContext实例。

如果您不希望发生这种情况,则需要执行以下操作

package com;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;

public class JAXBContextFactory {

    private static JAXBContext context = null;
    public static synchronized JAXBContext createJAXBContext() throws JAXBException {
        if(context == null){
            context = JAXBContext.newInstance(Customer.class);
        }
        return context;
    }

}

这和你的实现之间的区别在于,在这一个中,我们保存了在静态变量中创建的JAXBContext实例(保证只存在一次)。在您的实现中,您不会保存刚刚在任何位置创建的实例,并且每次调用该方法时都会创建一个新实例。重要提示:不要忘记添加到方法声明中的synchronized关键字,因为它确保在多线程环境中调用此方法仍然可以按预期工作。

答案 1 :(得分:3)

您的实现将为每个请求创建一个新的JAXBContext。相反,你可以这样做:

public class JAXBContextFactory {
    private static JAXBContext jaxbContext;

    static {
        try {
            jaxbContext = JAXBContext.newInstance(Customer.class);
        } catch (JAXBException ignored) {
        }
    }

    public static JAXBContext createJAXBContext() {
        return jaxbContext;
    }

}

答案 2 :(得分:3)

每次调用它时,您的方法都会清楚地创建一个新的JAXBContext。

如果你想确保只创建一个实例,无论你的方法被调用多少次,那么你正在寻找Singleton Pattern,其实现看起来像这样:

public class JAXBContextFactory {
  private static JAXBContext INSTANCE;
  public static JAXBContext getJAXBContext() throws JAXBException {
    if (JAXBContextFactory.INSTANCE == null) {
      INSTANCE = JAXBContext.newInstance(Customer.class);
    }
    return INSTANCE;
  }
}

请记住,此实例仅对每个Java类加载器都是唯一的。

答案 3 :(得分:2)

每次调用方法时都会有一个实例。使用static上下文仅表示您没有JAXBContextFactory

的任何实例

也许您使用的是

public enum JAXBContextFactory {;

    private static JAXBContext jaxbContext = null;

    public synchronized static JAXBContext createJAXBContext() throws JAXBException {
        if (jaxbContext == null)
            jaxbContext = JAXBContext.newInstance(Customer.class);
        return jaxbContext;
    }

}

答案 4 :(得分:0)

在分析了其他答案和@ tom-hawtin-tackline评论后,我认为最简单的解决方案是:

public class JAXBContextFactory {

    private static final JAXBContext CONTEXT = createContext();

    private static JAXBContext createContext() {
        try {
            return JAXBContext.newInstance(Customer.class);
        } catch (JAXBException e) {
            throw new AssertionError(e);
        }
    }

    public static JAXBContext getContext() { return CONTEXT; }

}