我如何正确使用Jackson ObjectMapper?

我很满意ObjectMapper如何工作和在我的应用程序中的一般用途。 我想了解的是实现ObjectMapper的最佳方式,以确保它被重用,我不在我的应用程序中创build不必要的实例?

我的想法是,我可以在Utils类中声明ObjectMapper,如下所示:

public class Utils { public final static ObjectMapper mapper = new ObjectMapper(); } 

然后我可以从我需要使用的代码的各个地方引用这个:

 JsonSimple jsonSimple = Utils.mapper.readValue(jsonString, JsonSimple.class); 

我遇到了另一个问题( 我应该宣布jackson的ObjectMapper是一个静态字段? ),这促使我的方法。 我想也许关键的区别是,我想分享我的ObjectMapper实例跨越许多不同的类,而不只是在一个类。

这种方法听起来合适吗?还是我错过了什么?

谢谢

在每个应用程序中使用单个实例是可以的,只要在调用可见之后不调用任何configuration方法即应该在静态块中完成所有初始化。

使用最新版本的Jackson,使用ObjectReaderObjectWriter代替ObjectMapper

正如在其他答案发布,ObjectMapper确实是线程安全的。 但是重复使用同一个对象可能会降低应用程序的性能,因为在给定时间可以locking全部1个线程,等待锁的所有者完成JSON的序列化/反序列化。

这在Jetty或Tomcat等Web服务器上尤为重要:例如,如果使用单例ObjectMapper作为REST服务的入口/出口点,整个服务器的整体性能可能会受到影响 – 当然,这取决于您的访问加载。

所以,我的build议是使用一个ObjectMapper池,允许多个线程使用它,并且在某种情况下,您不必在每次需要时都重新创build映射器。 池中ObjectMapper的数量应该与应用程序的工作线程数相同。

更多关于: http : //jackson-users.ning.com/forum/topics/pooling-objectmapper-for-performance

– 编辑 –

好吧,有些用户对Jackson的lib很有兴趣,他们甚至没有看链接的网站就低估了这个答案。 无论如何,这个答案是基于我的经验,在没有任何修改的lib(只是使用ObjectMapper,没有额外的类,没有自定义的序列化程序,没有自定义的JSONFactory,没有)在答案(2013年)的时候。 我不再使用它在我的项目,所以我不知道更新的版本 – 但我想现在应该解决。

作为开发人员,如果您打算直接或间接使用Jackson或任何其他JSON读写器,请考虑在您的服务器上运行分析工具,以查看线程在高负载情况下的performance。 这是一个不伤害的简单步骤。

你在你的问题中提出的纯静态单例是正确的。 另一种方法是使用单例模式( 在回答对类似问题的回答中已经详细讨论了单例模式的使用 )。 这是一个简单的例子:

 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); 

这是安全的,因为configuration后 ObjectMapper是线程安全的 。

警告:正如@StaxMan在回答评论中指出的那样,这并不能保证在返回的单身人士上进一步(重新)configuration。