2012-03-29 69 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)); 
} 

相關問題