내가 파일의 큰 세트를 처리하는 JAXB 비 정렬 화의 성능을 향상시킬 수있는 방법을 찾아 둘러보고 된 JAXB의 풀을 Unmarshaller에를 만들고 발견다음과 같은 조언을
"당신이 정말로, 성능에 대해 걱정하는 경우 및/또는 응용 프로그램이 많은 작은 문서를 읽는다면 Unmarshaller를 만드는 것이 상대적으로 비용이 많이 드는 작업 일 수 있습니다.이 경우 Unmarshaller 객체를 풀링하는 것이 좋습니다. "
예를 찾기 위해 웹 검색을하면 아무것도 반환되지 않았습니다. 그래서 Spring 3.0과 Apache Commons Pool을 사용하여 여기에 구현하는 것이 흥미로울 것이라고 생각했다. JAXB 프로 Unmarshaller에이 필요
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);
}
}
그리고 당신의 클래스
UnmarshallerFactory.java
// 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) {
}
}
}
이 예는 순진하다 JAXBContext이며 Keyed Po에 대한 키와 동일한 Class 인스턴스를 사용합니다. ol. 이것은 하나의 클래스가 아니라 매개 변수로 클래스 배열을 전달함으로써 향상시킬 수 있습니다.
희망이 도움이 될 수 있습니다.
음 ....이 질문은 .... 아니. – lscoughlin
글쎄, 내가 어디서 어떻게 질문을하지 않는 주제를 만들 수 있는지 모르겠다. –
안녕하세요, 저는 이것이 가치가 있다고 생각합니다. 그래서 SO는 "자신의 질문에 대답"을 할 수 있습니다. 아마도 당신이 질문의 형태로 게시물을 재구성 할 수 있고 당신이 받아 들일 수있는 "대답"으로 당신의 구현을 제공 할 수 있습니다. –