我将Jackson JSON处理器包装在自己的类中,但是还没有找到确定的线程安全和高性能的方式来处理共享实例。
根据文档,ObjectMapper
,ObjectWriter
和ObjectReader
都是线程安全的,我应该优先使用ObjectWriter
和ObjectReader
。
处理ObjectWriter
非常简单,但是即使在Jackson Data-bind docs上也没有明确的ObjectReader
指令,这暗示着我应该创建所有自己的ObjectReaders
并缓存它们。所以这就是我所做的:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;
import java.util.HashMap;
import java.util.Map;
public class JacksonEngine extends JsonProcessor {
private ObjectMapper mapper = new ObjectMapper();
private ObjectWriter writer = mapper.writer();
private Map<Class, ObjectReader> readers = new HashMap<>();
public String serialize(Object object) throws Exception {
return writer.writeValueAsString(object);
}
public <T> T deserialize(String json, Class<T> classOfT)
throws Exception {
if (!readers.containsKey(classOfT)) {
readers.put(classOfT, mapper.readerFor(classOfT));
}
return readers.get(classOfT).readValue(json);
}
}
这行得通吗?
我假设必须将哈希映射键的所有通用
Class<T>
减少为非通用Class
都可以。我还假设在多线程条件下将新的
if not present then add
放入缓存的非原子Readers
操作将不是问题,除非可能会创建一两个冗余读取器。最后,我认为为了提高性能,值得对
Readers
进行缓存,即使我没有在网上找到有关这样做的示例。 最佳答案
我认为您实际上并不需要ObjectReader
和ObjectWriter
。它们是线程安全的,因此可以共享。由于您不共享读者和作家,因此可以保持简单:
public class JacksonEngine extends JsonProcessor {
private final static ObjectMapper mapper = new ObjectMapper();
public String serialize(Object object) throws Exception {
return mapper.writeValueAsString(object);
}
public <T> T deserialize(String json, Class<T> classOfT)
throws Exception {
return mapper.readValue(json, classOfT);
}
}
更新:
由于OP每次调用新的阅读器时都会在调用
ObjectMapper.readValue()
时关注性能。查看源代码可以发现情况并非如此:public <T> T readValue(String content, Class<T> valueType) {
return (T) _readMapAndClose(_jsonFactory.createParser(content), _typeFactory.constructType(valueType));
}
protected Object _readMapAndClose(JsonParser p0, JavaType valueType) {
try {
Object result;
// ...
JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, valueType);
// ...
result = deser.deserialize(p, ctxt);
// ...
return result;
}
}