概括
我想找到使用 ObjectMapper
和/或 ObjectReader
在下面描述的用例上下文中的线程安全性和性能方面的最佳实践。
背景
我有一个帮助程序类 ( Json.java ),其中方法 toObject()
使用 ObjectMapper
从 json
对象转换为给定的 json-mapp- 字符串) 班级。
问题/问题
我读过 ObjectReader
通常被推荐为完全线程安全的,但我主要看到它处于非泛型上下文中,其中预定义了要读取的类。在这种情况下,您认为在线程安全和性能方面的最佳实践是什么?在代码中,我有三个建议可以作为起点。
我试图查看 jackson-databind
的源代码和文档,但我的 Java 理论技能还不足以从中得出答案。我也在 SO 和其他地方看过类似的问题,但没有发现任何与我的情况足够接近的问题。
import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
public abstract class Json {
private static final ObjectMapper jsonMapper = new ObjectMapper();
// NOTE: jsonReader is only relevant for Suggestion 3.
private static final ObjectReader jsonReader = jsonMapper.reader();
// Suggestion 1:
public static <T> T toObject1(final Class<T> type, final String json) throws IOException {
return jsonMapper.readValue(json, type);
}
// Suggestion 2:
public static <T> T toObject2(final Class<T> type, final String json) throws IOException {
return jsonMapper.readerFor(type).readValue(json);
}
// Suggestion 3:
public static <T> T toObject3(final Class<T> type, final String json) throws IOException {
return jsonReader.forType(type).readValue(json);
}
// Remainder of class omitted for brevity.
}
原文由 axeleration 发布,翻译遵循 CC BY-SA 4.0 许可协议
构造一个
ObjectMapper
实例是一个比较昂贵的操作,所以建议创建一个对象并重用它。你做对了final
。您总是将 JSON 读取 为 POJO,所以让我们准确明了,并使用
ObjectReader
。没有区别,真的。这两种方法都将构造一个新的
ObjectReader
对象:前者 (jsonMapper.readerFor(type)
) 将直接为您提供一个完整的实例,后者 (jsonReader.forType(type)
-e40c2d62d69be217-e40c2d62d69be217-e40c2 not-yet-usablejsonReader
并返回一个随时可用的对象。我宁愿选择选项 2,因为我不想保留该字段。您不必担心性能或线程安全。尽管创建
ObjectMapper
可能成本高昂(或从中复制),但获取和使用ObjectReader
s 是轻量级且完全线程安全的。来自 Java 文档(强调我的):
我自己最近有这些问题,并决定将
ObjectMapper#reader(InjectableValues)
作为工厂方法。这非常方便,特别是当您想要稍微自定义ObjectReader
或像我的情况一样调整DeserializationContext
。顺便说一句,这是一个很好的问题。