如何正确重用 Jackson ObjectMapper?

2022-08-31 13:21:28

我对ObjectMapper的工作方式和应用程序中的一般使用感到满意。我想了解的是实现ObjectMapper的最佳方法,以确保它被重用,并且我不会在我的应用程序中创建不必要的实例?

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

public class Utils {

    public final static ObjectMapper mapper = new ObjectMapper();

}

然后,我可以从我需要使用代码的各个位置引用它,例如:

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

我遇到了另一个问题(我应该将Jackson的ObjectMapper声明为静态字段吗?),这促使我的方法。我认为也许关键的区别在于,我想在许多不同的类之间共享我的 ObjectMapper 实例,而不仅仅是在单个类中。

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

谢谢


答案 1

每个应用程序使用一个实例是可以的,前提是您在使其可见后不调用任何配置方法,即您应该在静态块中完成所有初始化。


答案 2

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

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

因此,我的建议是使用一个对象映射器池,以允许多个线程使用它,并且在某种程度上,您不必在每次需要映射器时都重新创建映射器。池中对象映射程序的数目应与应用程序的工作线程数相同。

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

-- 编辑 --

好吧,一些用户对Jackson lib充满热情,以至于他们甚至没有查看链接的网站就否决了这个答案。无论如何,这个答案是基于我在回答时(2013年)没有任何修改的库经验(只是使用ObjectMapper,没有额外的类,没有自定义序列化程序,没有自定义JSONFactory,什么都没有)。我不再在我的项目中使用它,所以我不知道更新的版本 - 但我想它现在应该已经解决了。

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


推荐