我环顾四周寻找一种方法来提高JAXB解组表演处理文件的巨大集合,发现了以下建议:创建JAXB池的Unmarshaller
“如果你真正关心的性能,和/或你的应用程序将读取很多小文件,然后创建Unmarshaller可能是一个相对昂贵的操作。在这种情况下,考虑合并Unmarshaller对象“
谷歌搜索网络找到一个这样的例子没有返回任何东西,所以我认为使用Spring 3.0和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);
}
}
而在你的类,它需要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) {
}
}
}
这个例子是天真的,因为它仅使用一个类来创建JAXBContext并使用与Keyed Po相同的Class实例醇。这可以通过传递一个类的数组作为参数而不是只有一个类来改进。
希望这可以帮助。
严......这不是一个问题.... – lscoughlin 2011-04-01 07:53:44
那么我不知道在哪里如何创建一个不是问题的话题。 – 2011-04-04 05:33:47
嗨,我认为这很有价值,因此SO允许“回答自己的问题”,也许作为一个建议,你可以以问题的形式重构你的文章,并提供你的实现作为一个“答案”,然后你可以接受。 – 2012-09-11 07:15:39