JAXB creating context and marshallers cost

后端 未结 8 2105
情深已故
情深已故 2020-11-28 02:00

The question is a bit theoretical, what is the cost of creating JAXB context, marshaller and unmarshaller?

I\'ve found that my code could benefit from keeping the sa

8条回答
  •  情深已故
    2020-11-28 02:36

    I usually solve problems like this with a ThreadLocal class pattern. Given the fact that you need a different marshaller for each Class, you can combine it with a singleton-map pattern.

    To save you 15 minutes, of work. Here follows my implementation of a thread-safe Factory for Jaxb Marshallers and Unmarshallers.

    It allows you to access the instances as follows ...

    Marshaller m = Jaxb.get(SomeClass.class).getMarshaller();
    Unmarshaller um = Jaxb.get(SomeClass.class).getUnmarshaller();
    

    And the code you will need is a little Jaxb class that looks as follows:

    public class Jaxb
    {
      // singleton pattern: one instance per class.
      private static Map singletonMap = new HashMap<>();
      private Class clazz;
    
      // thread-local pattern: one marshaller/unmarshaller instance per thread
      private ThreadLocal marshallerThreadLocal = new ThreadLocal<>();
      private ThreadLocal unmarshallerThreadLocal = new ThreadLocal<>();
    
      // The static singleton getter needs to be thread-safe too, 
      // so this method is marked as synchronized.
      public static synchronized Jaxb get(Class clazz)
      {
        Jaxb jaxb =  singletonMap.get(clazz);
        if (jaxb == null)
        {
          jaxb = new Jaxb(clazz);
          singletonMap.put(clazz, jaxb);
        }
        return jaxb;
      }
    
      // the constructor needs to be private, 
      // because all instances need to be created with the get method.
      private Jaxb(Class clazz)
      {
         this.clazz = clazz;
      }
    
      /**
       * Gets/Creates a marshaller (thread-safe)
       * @throws JAXBException
       */
      public Marshaller getMarshaller() throws JAXBException
      {
        Marshaller m = marshallerThreadLocal.get();
        if (m == null)
        {
          JAXBContext jc = JAXBContext.newInstance(clazz);
          m = jc.createMarshaller();
          marshallerThreadLocal.set(m);
        }
        return m;
      }
    
      /**
       * Gets/Creates an unmarshaller (thread-safe)
       * @throws JAXBException
       */
      public Unmarshaller getUnmarshaller() throws JAXBException
      {
        Unmarshaller um = unmarshallerThreadLocal.get();
        if (um == null)
        {
          JAXBContext jc = JAXBContext.newInstance(clazz);
          um = jc.createUnmarshaller();
          unmarshallerThreadLocal.set(um);
        }
        return um;
      }
    }
    

提交回复
热议问题