2012-03-29 72 views
0

我已经采取了以下线从博客把一个资源创建调用静态块内,将使它创造一次为整个应用程序

的一个唯一的办法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; 
    } 

回答

1

可以使用Singleton模式,

例如:

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对象应用程序

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

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

我的问题是,对于整个Web应用程序(来自不同用户的请求)是否只有一个JAXBContext存在? – Pawan 2012-03-29 11:41:12

+0

理论上,是的,会有。您需要注意线程同步。在web应用程序中,每个请求都在一个单独的线程中处理,所以您应该同步创建'jaxbContext'。根据部署情况,您最终可能会使用不同的类加载器实例加载多个应用程序副本,在这种情况下,每个类加载器都会有一个副本。 – 2012-03-29 11:46:24

+0

这很好,因为它只通过应用程序给出它的一个实例,但为什么人们使用Singleton? – Pawan 2012-03-29 11:50:11

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

相关问题