2011-04-01 8 views
7

szukałem wokół, aby znaleźć sposób na poprawę JAXB występy Unmarshalling przetwarzanie dużych zbiorów plików i znaleźć następujące informacje:Tworzenie puli JAXB Unmarshaller

„Jeśli naprawdę dbają o wydajność i/lub Twoja aplikacja odczyta wiele małych dokumentów, a następnie utworzenie Unmarshallera może być względnie kosztowną operacją. W takim przypadku rozważ użycie puli obiektów Unmarshaller "

Wyszukiwarka w internecie, aby znaleźć przykład, nie zwróciła niczego , więc pomyślałem, że może być interesujące umieszczenie mojej implementacji za pomocą Spring 3.0 i Apache Commons Pool.

UnmarshallerFactory.java

import java.util.HashMap; 
import java.util.Map; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import org.apache.commons.pool.KeyedPoolableObjectFactory; 
import org.springframework.stereotype.Component; 

/** 
* Pool of JAXB Unmarshallers. 
* 
*/ 
@Component 
public class UnmarshallerFactory implements KeyedPoolableObjectFactory { 
    // Map of JAXB Contexts 
    @SuppressWarnings("rawtypes") 
    private final static Map<Object, JAXBContext> JAXB_CONTEXT_MAP = new HashMap<Object, JAXBContext>(); 

    @Override 
    public void activateObject(final Object arg0, final Object arg1) throws Exception { 
    } 

    @Override 
    public void passivateObject(final Object arg0, final Object arg1) throws Exception { 
    } 

    @Override 
    public final void destroyObject(final Object key, final Object object) throws Exception { 
    } 

    /** 
    * Create a new instance of Unmarshaller if none exists for the specified 
    * key. 
    * 
    * @param unmarshallerKey 
    *   : Class used to create an instance of Unmarshaller 
    */ 
    @SuppressWarnings("rawtypes") 
    @Override 
    public final Object makeObject(final Object unmarshallerKey) { 
     if (unmarshallerKey instanceof Class) { 
      Class clazz = (Class) unmarshallerKey; 
      // Retrieve or create a JACBContext for this key 
      JAXBContext jc = JAXB_CONTEXT_MAP.get(unmarshallerKey); 
      if (jc == null) { 
       try { 
        jc = JAXBContext.newInstance(clazz); 
        // JAXB Context is threadsafe, it can be reused, so let's store it for later 
        JAXB_CONTEXT_MAP.put(unmarshallerKey, jc); 
       } catch (JAXBException e) { 
        // Deal with that error here 
        return null; 
       } 
      } 
      try { 
       return jc.createUnmarshaller(); 
      } catch (JAXBException e) { 
       // Deal with that error here 
      } 
     } 
     return null; 
    } 

    @Override 
    public final boolean validateObject(final Object key, final Object object) { 
     return true; 
    } 
} 

UnmarshallerPool.java

import org.apache.commons.pool.impl.GenericKeyedObjectPool; 
import org.apache.log4j.Logger; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Component; 

@Component 
public class UnmarshallerPool extends GenericKeyedObjectPool { 
    @Autowired 
    public UnmarshallerPool(final UnmarshallerFactory unmarshallerFactory) { 
    // Make usage of the factory created above 
    super(unmarshallerFactory); 
      // You'd better set the properties from a file here 
    this.setMaxIdle(4); 
    this.setMaxActive(5); 
    this.setMinEvictableIdleTimeMillis(30000); 
    this.setTestOnBorrow(false); 
    this.setMaxWait(1000); 
    } 

    public UnmarshallerPool(UnmarshallerFactory objFactory, 
     GenericKeyedObjectPool.Config config) { 
     super(objFactory, config); 
    } 

    @Override 
    public Object borrowObject(Object key) throws Exception { 
     return super.borrowObject(key); 
    } 

    @Override 
    public void returnObject(Object key, Object obj) throws Exception { 
     super.returnObject(key, obj); 
    } 
} 

A w swojej klasie, które wymagają JAXB Unmarshaller:

// Autowiring of the Pool 
    @Resource(name = "unmarshallerPool") 
    private UnmarshallerPool unmarshallerPool; 

    public void myMethod() { 
     Unmarshaller u = null; 
     try { 
      // Borrow an Unmarshaller from the pool 
      u = (Unmarshaller) this.unmarshallerPool.borrowObject(MyJAXBClass.class); 
      MyJAXBClass myJAXBObject = (MyJAXBClass) u.unmarshal(url); 
      // Do whatever 
     } catch (Exception e) { 
      // Deal with that error 
     } finally { 
      try { 
       // Return the Unmarshaller to the pool 
       this.unmarshallerPool.returnObject(MyJAXBClass.class, u); 
      } catch (Exception ignore) { 
      } 
     } 
    } 

Ten przykład jest naiwny, ponieważ używa tylko jedną klasę, aby stworzyć JAXBContext i używa tej samej instancji klasy, co klucz dla klucza Keyed Po ol. Można to poprawić, przekazując Array of Classes jako parametr, a nie tylko jedną klasę.

Mam nadzieję, że to pomoże.

+3

Uhm .... to nie jest pytanie ... – lscoughlin

+1

No nie wiem gdzie mogę stworzyć temat, który nie jest pytaniem. –

+0

Witam, myślę, że to jest cenne, a SO pozwala na "odpowiadanie na własne pytania", może jako poradę mógłbyś zrestrukturyzować swój post w formie pytania i dostarczając swoją implementację jako "odpowiedź", którą następnie możesz zaakceptować. –

Odpowiedz

0

Tworzenie unmarshallerów ma być światłem. Polecam zrobić profilowanie przed opracowaniem strategii łączenia.

+5

Jak już powiedziałem, wszystko opiera się na radzie, którą można znaleźć pod numerem here, informując, że tworzenie wielu programów Unmarshallers może być kosztowną operacją. Nawet bez profilowania mogę powiedzieć, że moja aplikacja działa znacznie szybciej dzięki łączeniu Unmarshaller. –

+1

Stworzenie programu unmarshallers JXAB NIE JEST ŚWIATŁEM, bez względu na intencję. – Hector

Powiązane problemy