SpringBoot中如何使用ObjectMapper,老鸟们都是这样玩的?

发布时间:2025-05-18 01:48:42 作者:益华网络 来源:undefined 浏览量(1) 点赞(1)
摘要:来源:JAVA日知录 1. 每次new一个 在SpringBoot项目中要实现对象与Json字符串的互转,每次都需要像如下一样new 一个ObjectMapper对象:publicUserEntitystring2Obj(Stringjson)throwsJsonProcessingExcepti

来源:JAVA日知录

1. 每次new一个

在SpringBoot项目中要实现对象与Json字符串的互转,每次都需要像如下一样new 一个ObjectMapper对象:

public UserEntity string2Obj(String json) throws JsonProcessingException 

{

 ObjectMapper objectMapper = new

 ObjectMapper();

 return objectMapper.readValue(json, UserEntity.class)

;

}

public String obj2String(UserEntity userEntity) throws JsonProcessingException 

{

 ObjectMapper objectMapper = new

 ObjectMapper();

 return

 objectMapper.writeValueAsString(car)

}

这样的代码到处可见,有问题吗?

你要说他有问题吧,确实能正常执行;可你要说没问题吧,在追求性能的同学眼里,这属实算是十恶不赦的代码了。

首先,让我们用JMH对这段代码做一个基准测试,让大家对其性能有个大概的了解。

基准测试是指通过设计科学的测试方法、测试工具和测试系统,实现对一类测试对象的某项性能指标进行定量的和可对比的测试。而JMH是一个用来构建,运行,分析Java或其他运行在JVM之上的语言的 纳秒/微秒/毫秒/宏观 级别基准测试的工具。

@BenchmarkMode

(Mode.Throughput)

@OutputTimeUnit

(TimeUnit.SECONDS)

@State

(Scope.Thread)

@Fork(1

)

@Warmup(iterations = 5, time = 1

)

@Measurement(iterations = 3, time = 1

)

public class JsonJMHTest 

{

    String json = "{\"id\":122345667,\"email\":\"jianzh5@163.com\",\"price\":12.25}"

;

    UserEntity userEntity = new UserEntity(13345L,"jianzh5@163.com", BigDecimal.valueOf(12.25

));

    

/**

     * 测试String to Object

     */
    @Benchmark    public UserEntity objectMapper2ObjTest() throws JsonProcessingException 

{

        ObjectMapper objectMapper = new

 ObjectMapper();

        return objectMapper.readValue(json, UserEntity.class)

;

    }

    

/**

     * 测试Object to String

     */
    @Benchmark    public String objectMapper2StringTest() throws JsonProcessingException 

{

        ObjectMapper objectMapper = new

 ObjectMapper();

        return

 objectMapper.writeValueAsString(userEntity);

    }

   public static void main(String[] args) throws RunnerException 

{

        Options opt = new

 OptionsBuilder()

                .include(JsonJMHTest.class.getSimpleName

())

                .build()

;

        new

 Runner(opt).run();

    }

}

测试环境

# JMH version: 1.36# VM version: JDK 17.0.3, OpenJDK 64-Bit Server VM, 17.0.3+7-LTS# Mac AppleM1/16GB

测试结果

通过测试结果可以看出,每次new一个ObjectMapper,在实现字符串转对象时每秒可以完成23万多次,而实现对象转Json字符串每秒仅可完成2.7万次。

那该如何优化,提升性能呢?

2. 单例化

老鸟们都知道,在创建工具类时要将工具类设置成单例的,这样不仅可以保证线程安全,也可以保证在系统全局只能创建一个对象,避免频繁创建对象的成本。

所以,我们可以在项目中构建一个ObjectMapper的单例类。

@Getterpublic enum

 ObjectMapperInstance {

    INSTANCE;

    private final ObjectMapper objectMapper = new

 ObjectMapper();

    ObjectMapperInstance() {

    }

}

再次使用JMH对其测试:

@Benchmarkpublic UserEntity singleten2ObjTest() throws JsonProcessingException 

{

  ObjectMapper objectMapper = ObjectMapperInstance.INSTANCE.getObjectMapper();

  return objectMapper.readValue(json, UserEntity.class)

;

}

@Benchmarkpublic String singleten2StringTest() throws JsonProcessingException 

{

  ObjectMapper objectMapper = ObjectMapperInstance.INSTANCE.getObjectMapper();

  return

 objectMapper.writeValueAsString(userEntity);

}

测试结果如下:

可以看到,使用单例模式,String转对象的方法每秒可以执行420多万次,比new ObjectMapper的方式快了18倍;而对象转String的方法每秒可以执行830万次,性能提升了300倍(看到结果的一瞬间我傻眼了,一度怀疑是写错代码了)!!!!

3. 个性化配置

当然,在项目中使用ObjectMapper时,有时候我们还需要做一些个性化配置,比如将Long和BigDemical类型的属性都通过字符串格式进行转换,防止前端使用时丢失数值精度。

这些类型转换的格式映射都可以在单例类中配置,代码如下:

@Getterpublic enum

 ObjectMapperInstance {

    INSTANCE;

    private final

 ObjectMapper objectMapper;

    ObjectMapperInstance() {

        objectMapper = new

 ObjectMapper();

        // 注册自定义模块

        initialize();

    }

    private void initialize() 

{

        CustomJsonModule customJsonModule = new

 CustomJsonModule();

        objectMapper.registerModule(customJsonModule);

    }

}

在initialize()方法中给ObjectMapper注册自定义序列化转换器。

第一行是使用注册自定义序列换转换器后的效果,给id和price字段都加上了引号。

再来一次JMH测试:

可以看到,给ObjectMapper额外注册转换类型以后性能会受到一定的影响,但对业务影响不大。(啥业务能这么高的请求~)

4. 小结

通过上面的测试,结论已经很清晰了。使用单例模式进行字符串转对象时性能可以提升18倍,而对象转String性能快了惊人的290万倍,所以在Spring中如何正确的使用ObjectMapper不用我再说了吧~

DailyMart是一个基于领域驱动设计(DDD)和Spring Cloud Alibaba的微服务商城系统。我们将在该系统中整合博主其他专栏文章的核心内容。如果你对这两大技术栈感兴趣,可以在本公众号回复关键词 DDD 以获取相关源码。

二维码

扫一扫,关注我们

声明:本文由【益华网络】编辑上传发布,转载此文章须经作者同意,并请附上出处【益华网络】及本页链接。如内容、图片有任何版权问题,请联系我们进行处理。

感兴趣吗?

欢迎联系我们,我们愿意为您解答任何有关网站疑难问题!

您身边的【网站建设专家】

搜索千万次不如咨询1次

主营项目:网站建设,手机网站,响应式网站,SEO优化,小程序开发,公众号系统,软件开发等

立即咨询 15368564009
在线客服
嘿,我来帮您!