2011-04-01 30 views
7

Tôi đã nhìn xung quanh để tìm một cách để cải thiện JAXB biểu diễn unmarshalling chế biến tập khổng lồ các tập tin và tìm thấy những lời khuyên sau đây:Tạo một hồ bơi của JAXB Unmarshaller

"Nếu bạn thực sự quan tâm về hiệu suất, và/hoặc ứng dụng của bạn sẽ đọc rất nhiều tài liệu nhỏ, sau đó tạo Unmarshaller có thể là một hoạt động tương đối đắt tiền. Trong trường hợp đó, hãy xem xét gộp các đối tượng Unmarshaller "

Googling web để tìm một ví dụ về điều này không trả về bất cứ điều gì , vì vậy tôi nghĩ rằng có thể có ích khi đặt triển khai của tôi ở đây bằng cách sử dụng Spring 3.0 và 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); 
    } 
} 

Và trong lớp học của bạn đòi hỏi một 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) { 
      } 
     } 
    } 

Ví dụ này là ngây thơ vì nó chỉ sử dụng một lớp để tạo ra các JAXBContext và sử dụng cùng một cá thể Lớp làm Khóa cho Khóa được đánh dấu ol. Điều này có thể được cải thiện bằng cách chuyển một Array of Classes thành tham số thay vì chỉ một Class.

Hy vọng điều này có thể hữu ích.

+3

Uhm .... đây không phải là câu hỏi .... – lscoughlin

+1

Tôi cũng không biết làm cách nào để tạo chủ đề không phải là câu hỏi. –

+0

Hi túp lều, tôi nghĩ rằng điều này có giá trị và SO cho phép "trả lời câu hỏi của riêng", có thể là một lời khuyên bạn có thể tái cấu trúc bài đăng của mình dưới dạng câu hỏi và cung cấp cho bạn một câu trả lời "" mà bạn có thể chấp nhận. –

Trả lời

0

Việc tạo unmarshallers được dự định là ánh sáng. Tôi sẽ khuyên bạn nên làm một số hồ sơ trước khi phát triển một chiến lược tổng hợp.

+5

Như tôi đã nói đây là tất cả dựa trên lời khuyên tìm thấy here nói rằng sự khởi tạo của nhiều Unmarshallers có thể là một hoạt động tốn kém. Ngay cả khi không có hồ sơ, tôi có thể cho bạn biết rằng ứng dụng của tôi chạy nhanh hơn nhiều với tính năng tổng hợp Unmarshaller. –

+1

Việc tạo ra các unmarshallers JXAB không phải là LIGHT, bất kể ý định là gì. – Hector

Các vấn đề liên quan