我对ObjectMapper如何工作以及在我的应用程序中的一般用途感到满意。我想了解的是实现ObjectMapper的最佳方法,以确保它被重用,我不是在我的应用程序中创建不必要的实例?
我的想法是我可以在Utils类中声明ObjectMapper,如下所示:
public class Utils {
public final static ObjectMapper mapper = new ObjectMapper();
}
然后我可以从我需要使用代码的各个地方引用它,例如:
JsonSimple jsonSimple = Utils.mapper.readValue(jsonString, JsonSimple.class);
我遇到了另一个提示我的方法的问题(Should I declare Jackson's ObjectMapper as a static field?)。我想可能关键的区别在于我想在多个不同的类中共享我的ObjectMapper实例,而不仅仅是在一个类中。
这种方法听起来合适还是我错过了什么?
由于
答案 0 :(得分:41)
每个应用程序使用一个实例是很好的,前提是你在任何配置方法可见之后都不会调用它,即你应该在静态块中进行所有初始化。
答案 1 :(得分:8)
正如其他答案所述,ObjectMapper确实是Thread安全的。但重用相同的对象会降低应用程序的性能,因为在给定时间可以锁定所有1个线程,等待锁的所有者完成JSON的序列化/反序列化。
这对于Jetty或Tomcat等Web服务器尤其重要:例如,如果使用单例ObjectMapper作为REST服务的入口/出口点,整个服务器的整体性能可能会受到影响 - 当然,这取决于在您的访问负载上。
所以,我的建议是使用一个ObjectMappers池,允许多个线程使用它,并且在某种程度上你不必在每次需要时重新创建映射器。池中ObjectMappers的编号应与应用程序的工作线程数相同。
更多关于:http://jackson-users.ning.com/forum/topics/pooling-objectmapper-for-performance
- 编辑 -
好吧,有些用户真的对Jackson lib充满热情,以至于他们甚至没有查看链接的网站就会回答这个问题。无论如何,这个答案是基于我在没有任何修改的情况下使用lib的经验(仅使用ObjectMapper,没有额外的类,没有自定义序列化器,没有自定义JSONFactory,没有),在回答时(2013)。我不再在我的项目上使用它,所以我不知道更新的版本 - 但我想它现在应该解决了。
作为开发人员,如果您要在项目中直接或间接使用Jackson或任何其他JSON读取器/写入器,请考虑在服务器上运行性能分析工具,以查看线程在高负载下的行为方式。这是一个不会造成伤害的简单步骤。
答案 2 :(得分:5)
使用最新版本的Jackson并使用ObjectReader
和ObjectWriter
代替ObjectMapper
答案 3 :(得分:1)
您在问题中提出的普通静态单例是正确的。另一种方法是使用单例模式(the use of singleton pattern been discussed at length in answer comments to a similar question)。这是一个简单的例子:
public enum Mapper {
INSTANCE;
private final ObjectMapper mapper = new ObjectMapper();
private Mapper(){
// Perform any configuration on the ObjectMapper here.
}
public ObjectMapper getObjectMapper() {
return mapper;
}
}
然后您可以使用(并重复使用)ObjectMapper
单例,如下所示:
ObjectMapper mapper = Mapper.INSTANCE.getObjectMapper();
JsonSimple jsonSimple = mapper.readValue(jsonString, JsonSimple.class);
这是安全的,因为ObjectMapper
是thread-safe after configuration。
警告:正如@StaxMan在答案评论中指出的那样,这并不保证不会对返回的单例进行进一步(重新)配置。