Redian新闻
>
SpringBoot中这样用ObjectMapper,才够优雅!

SpringBoot中这样用ObjectMapper,才够优雅!

公众号新闻

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入芋道快速开发平台知识星球。下面是星球提供的部分资料: 

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、CRM 等等功能:

  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本 

来源:JAVA日知录


每次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\":\"[email protected]\",\"price\":12.25}";
    UserEntity userEntity = new UserEntity(13345L,"[email protected]", 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();
    }
}

测试环境


> 基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
>
> * 项目地址:<https://github.com/YunaiV/ruoyi-vue-pro>
> * 视频教程:<https://doc.iocoder.cn/video/>

# 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万次。

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

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

单例化

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

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

@Getter
public enum ObjectMapperInstance {

    INSTANCE;

    private final ObjectMapper objectMapper = new ObjectMapper();

    ObjectMapperInstance() {

    }
}

再次使用JMH对其测试:

@Benchmark
public UserEntity singleten2ObjTest() throws JsonProcessingException {
        ObjectMapper objectMapper = ObjectMapperInstance.INSTANCE.getObjectMapper();
        return objectMapper.readValue(json, UserEntity.class);
        }

@Benchmark
public String singleten2StringTest() throws JsonProcessingException {
        ObjectMapper objectMapper = ObjectMapperInstance.INSTANCE.getObjectMapper();
        return objectMapper.writeValueAsString(userEntity);
        }

测试结果如下:

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

个性化配置

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

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

@Getter
public 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额外注册转换类型以后性能会受到一定的影响,但对业务影响不大。(啥业务能这么高的请求~)

小结

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


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,长按”或“扫描”下方二维码噢

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

文章有帮助的话,在看,转发吧。

谢谢支持哟 (*^__^*)

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
来了个从阿里跳槽来的工程师,写个 try catch 的方式都这么优雅!Spring Boot 3.2 和 Spring Framework 6.1添加对 Java 21、虚拟线程和 CRaC 的支持【会计师全职Offer】American Chengyi投资管理集团会计师录用Offer!|求职战报2023虽然过的不尽人意但是也要总结一下!【软件工程师Offer】Sirius XM软件工程师实习录用Offer!|求职战报如何在SpringBoot中优雅地重试调用第三方API?Looking Good: China’s Cosmetics Appeal to Overseas MarketsXM boosted by 175 overseas investment projects last year两首《万家灯火》KFC Sliders折扣,仅需$2!!!Pepper Mayo, BBQ and Supercharged三种口味可选!Wetlands Project Suspended After NGO Lawsuit竞赛春令营:Mathematica+Math League+CTMC+Kangaroo+趣味数学,超强阵容【数据分析师全职Offer】西奈医院Sinai Hospital录用Offer!|求职战报嫉妒的心灵不美丽爬藤规划的核心 :如何定制你的美本Impact Project?【会计师全职保录取Offer】TZG Accounting LLC录用Offer!|求职战报Spring Boot 封装一个万能 Excel 导出工具,传什么都能导出!【ERP全职Offer】Value Wholesaler录用Offer!|求职战报Spring Boot 如何快速过滤出一次请求的所有日志?Spring Boot 玩一玩代码混淆,防止反编译代码泄露Citing Safety, Beijing Bans Unregistered Electric ScootersSpringBoot Redis 分布式锁的正确实现方式Property to Virtual Goods, More Young Chinese Are Drafting Wills湖南大学聂舟团队Angew |工程化Anti-CRISPR蛋白创建CRISPR-Cas蛋白开关用于激活型基因编辑和病毒蛋白酶检测《再见,布里诺斯艾利斯》spring是“春天”,chicken是“鸡”,那spring chicken什么意思?[评测]Corsair Dominator Titanium RGB 48GB(2x24GB) DDR5 7200Mhz C36【会计师全职Offer】Eastern Accounting & Counsulting会计师录用Offer!|求职战报惠普推出星Book系列首款AIPC:星Book Pro 14求求你们别再用 kill -9 了,这才是 Spring Boot 停机的正确方式!!!Meta官方的Prompt工程指南:Llama 2这样用更高效关于朱令铊中毒的一点讨论亚马逊14亿美元收购iRobot计划被搅黄!iRobot宣布裁员350人王长虎:PixVerse 实测效果已超过 Pika,抖音经验让我们有足够优势录取捷报 | 美初高喜讯不断,再获三枚offer,包含宾州优质走读学校Baldwin及8年级转正Rectory!
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。