我有一个多线程 Java 应用程序,我在其中使用 Jackson 库。每次我需要 ObjectMapper 时,我都会在需要使用它的类中声明它。有时我使用 objectMapper.configure() 自定义此 ObjectMapper,但并非总是如此。 这是一个不好的做法吗?有没有办法只声明一两次?
我发现实例化 new ObjectMapper() 需要相当长的时间,所以你绝对应该重用该对象,而不是每次都创建它然后重复使用。
我通常将其声明为使用它的类中的记录器(但当然这取决于您的具体要求,这对您是否有意义):
private static final ObjectMapper objectMapper = new ObjectMapper();
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
...
尽可能重用对象映射器。因为它是线程安全的。如果任何类需要在对象映射器中进行不同的配置,则只能为此类类实例化单独的对象映射器。
我建议不要有相同配置的多个实例。
你最好使用单实例并在需要时注入。
对于 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;
}
}