Java 如何正确重用 Jackson ObjectMapper?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18611565/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 09:30:40  来源:igfitidea点击:

How do I correctly reuse Hymanson ObjectMapper?

javaHymanson

提问by nickebbitt

I am happy with how the ObjectMapper works and general use within my application. What I would like to understand is the best way to implement the ObjectMapper to ensure it is re-used and I'm not creating unnecessary instances within my application?

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

My thoughts are that I can declare the ObjectMapper in a Utils class as follows:

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

public class Utils {

    public final static ObjectMapper mapper = new ObjectMapper();

}

I could then reference this from the various places I need to using code such as:

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

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

I came across this other question (Should I declare Hymanson's ObjectMapper as a static field?) that prompted my approach. I think maybe the key difference is that I want to share my ObjectMapper instance across many different classes, not just within a single class.

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

Does this approach sound appropriate or am I missing something?

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

Thanks

谢谢

采纳答案by RokL

It's fine to use a single instance per application provided you don't call any configuration methods after it's been made visible i.e. you should do all your initialization inside a static block.

可以为每个应用程序使用单个实例,前提是您在它可见后不调用任何配置方法,即您应该在静态块中进行所有初始化。

回答by lorcan

The plain static singleton you proposed in your question is correct. An alternative approach would be to use the singleton pattern (the use of singleton pattern been discussed at length in answer comments to a similar question). Here's a simple example:

您在问题中提出的普通静态单身人士是正确的。另一种方法是使用单例模式(在对类似问题的回答评论中详细讨论了单例模式的使用)。这是一个简单的例子:

public enum Mapper {
  INSTANCE;
  private final ObjectMapper mapper = new ObjectMapper();

  private Mapper(){
    // Perform any configuration on the ObjectMapper here.
  }

  public ObjectMapper getObjectMapper() {
    return mapper;
  }
}

Then you can use (and reuse) the ObjectMappersingleton as follows:

然后你可以使用(和重用)ObjectMapper单例如下:

ObjectMapper mapper = Mapper.INSTANCE.getObjectMapper();
JsonSimple jsonSimple = mapper.readValue(jsonString, JsonSimple.class);

This is safe as ObjectMapperis thread-safe after configuration.

这是安全的,配置后ObjectMapper也是线程安全的

Caveat: As @StaxMan points out in the answer comments, this does NOT guarantee against further (re)configuration on the returned singleton.

警告:正如@StaxMan 在回答评论中指出的那样,这并不能保证对返回的单例进行进一步(重新)配置。

回答by Gilberto Torrezan

As posted in other answers, the ObjectMapper is indeed Thread safe. But reusing the same object can decrease the performance of your application, since all - 1 threads can be locked at a given time waiting for the owner of the lock to complete the serialization/deserialization of JSON.

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

This is especially critical on web servers such as Jetty or Tomcat: the overall performance of the entire server can be compromised, for instance, if you use the singleton ObjectMapper as entry/exit point of REST services - depending, of course, on your access load.

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

So, my suggestion is to use a pool of ObjectMappers, to allow multiple Threads to use it, and in a way you don't have to recreate the mappers every time you need them. The number to ObjectMappers in the pool should be the same number of worker Threads of your application.

因此,我的建议是使用 ObjectMappers 池,以允许多个线程使用它,并且您不必每次需要它们时都重新创建映射器。池中 ObjectMappers 的数量应该与您的应用程序的工作线程数量相同。

More about: http://Hymanson-users.ning.com/forum/topics/pooling-objectmapper-for-performance

更多信息:http: //Hymanson-users.ning.com/forum/topics/pooling-objectmapper-for-performance

-- EDIT --

- 编辑 -

Ok, some users are really passionate about the Hymanson lib to the point that they downvote this answer without even looking at the linked website. Anyway, this answer is based on my experience with the lib without any modifications (just using ObjectMapper, no extra classes, no custom serializer, no custom JSONFactory, nothing) at the time of the answer (2013). I don't use it anymore on my projects so I don't know about newer versions - but I guess it should be solved by now.

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

As developer, if you're going to use Hymanson or any other JSON reader/writer on your project, directly or indirectly, consider running a profiling tool on your server to see how the threads behave on high load. It's a simple step that doesn't harm.

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

回答by talebisia

Use the latest version of Hymanson and use ObjectReaderand ObjectWriterinstead of ObjectMapper

使用最新版本的 Hymanson 并使用ObjectReaderandObjectWriter代替ObjectMapper