我应该在每次需要时都声明 Jackson 的 ObjectMapper 吗?

问题描述 投票:0回答:4

我有一个多线程 Java 应用程序,我在其中使用 Jackson 库。每次我需要 ObjectMapper 时,我都会在需要使用它的类中声明它。有时我使用 objectMapper.configure() 自定义此 ObjectMapper,但并非总是如此。 这是一个不好的做法吗?有没有办法只声明一两次?

java jackson
4个回答
3
投票

我发现实例化 new ObjectMapper() 需要相当长的时间,所以你绝对应该重用该对象,而不是每次都创建它然后重复使用。

我通常将其声明为使用它的类中的记录器(但当然这取决于您的具体要求,这对您是否有意义):

  private static final ObjectMapper objectMapper = new ObjectMapper();

1
投票

Jackson

ObjectMapper
对于不同的情况有许多不同的配置参数,虽然可以跨线程共享一个实例来进行操作,但需要本质上不同的设置是完全正常的(例如,当您使用以下 REST API 时)使用
camel_case
命名,甚至使用 YAML 或 CSV 映射器)。

因此,我不建议制作

ObjectMapper
豆,就像我不建议制作
Function<Foo, Bar>
String
豆一样; Bean 类型不够具体。

相反,

ObjectMapper
更像是API部分,因为诸如“使用
camel_case
”或“将日期写入ISO 8601字符串”之类的设置不像缓存过期时间,它们反映了固定的部分合同的内容。

我建议创建工厂方法,它将根据用例的特定要求构建新实例。这些方法可以存在于整个公司共享的库中,以强制执行有关变量命名、日期/时间处理等的一致映射:

public static ObjectMapper companyObjectMapper() {
    // company-wide standard configuration
    ...
}

public static ObjectMapper specificRestApiObjectMapper() {
    // uses Unix epoch for dates and camel_case
    ...

1
投票

尽可能重用对象映射器。因为它是线程安全的。如果任何类需要在对象映射器中进行不同的配置,则只能为此类类实例化单独的对象映射器。

我建议不要有相同配置的多个实例。


0
投票

你最好使用单实例并在需要时注入。

对于 Spring 你应该使用:

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@Slf4j
public class ObjectMapperConfig {

    @Bean
    public ObjectMapper objectMapper() {

        final ObjectMapper objectMapper = new ObjectMapper();

        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        log.info("Exposed ObjectMapper as Spring Bean");
        return objectMapper;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.