序列化方式五——ProtoStuff

news2024/12/26 11:23:03

介绍

Protostuff是一个基于Java的高效序列化库,它使用Protocol Buffers(简称protobuf)协议,为Java对象提供高效、灵活且易用的序列化和反序列化方法。Protostuff的主要优势在于其高性能和简单的使用方式,相对于其他序列化库,如JSON或XML,它在处理大量数据时能够显著降低内存使用并提高传输速度。

特点

  1. 高效性:Protostuff采用紧凑的二进制编码方式,使得序列化后的字节数量较小,从而提高了传输效率和存储空间利用率。

  2. 灵活性:支持动态生成Schema,可以适应不同类型的Java对象,并且能够处理新增或删除字段的情况。此外,Protostuff还支持可插拔的格式,可以方便地集成到各种系统中。

  3. 易用性:Protostuff的使用非常简单,只需要在需要序列化的成员上加上Tag注解,并写明顺序即可。同时,官方文档也提供了详细的使用指南和示例代码。

优缺点

优点:

  • 高性能:在速度和内存管理上都表现出色,确保应用在处理大量数据时仍能保持流畅运行。

  • 灵活性高:支持动态生成Schema和可插拔的格式,适应性强。

  • 使用简单:相对于Protobuf等其他序列化库,Protostuff的使用更加简洁明了。

缺点:

  • 需要正确定义Schema:如果没有正确的Schema定义,将无法进行序列化和反序列化操作。

  • 不支持跨版本兼容:当Java对象的字段发生变化时(如新增或删除字段),可能会导致旧版本的字节流无法正常反序列化。因此,在使用Protostuff进行序列化和反序列化时,需要确保Java对象的类定义是稳定的,并且与对应的Schema一致。

与Protobuf的区别

  1. 使用简单性:相对于Protobuf需要编写接口定义文件并编译的繁琐操作,Protostuff的使用更加简单直接,只需在需要序列化的成员上添加Tag注解即可。

  2. 灵活性:虽然两者都支持动态生成Schema,但Protostuff在灵活性方面表现更佳,支持可插拔的格式以及更广泛的自定义选项。

  3. 性能:在性能方面,两者都表现出色。然而,具体性能取决于具体的使用场景和数据结构。一般来说,Protostuff在某些情况下可能具有更高的序列化和反序列化速度。

使用

添加依赖

<dependency>
  <groupId>io.protostuff</groupId>
  <artifactId>protostuff-core</artifactId>
  <version>1.8.0</version>
</dependency>
<dependency>
  <groupId>io.protostuff</groupId>
  <artifactId>protostuff-runtime</artifactId>
  <version>1.8.0</version>
</dependency>

实体类

package com.zhz.test.serialization.entity;

import io.protostuff.Tag;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author zhouhengzhe
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class ProtoStuffStudent {
    @Tag( 1)
    private String name;
    @Tag(2)
    private String studentNo;
    @Tag(3)
    private int age;
    @Tag(4)
    private String schoolName;
    @Tag(5)
    private Address address;
}

package com.zhz.test.serialization.entity;

import io.protostuff.Tag;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author zhouhengzhe
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Address {
    @Tag(1)
    private String province;
    @Tag(2)
    private String city;
}

工具类

package com.zhz.test.serialization.protostuff;

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author zhouhengzhe
 */
public class ProtobufUtils {

    //避免每次序列化都重新申请Buffer空间
    private static LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
    //缓存类对应的Schema,因为每次都会调用RuntimeSchema.getSchema,所以该方法会比较耗时,
    private static Map<Class<?>, Schema<?>> schemaCache = new ConcurrentHashMap<>();

    /**
     * 序列化方法,把指定对象序列化成字节数组
     */
    @SuppressWarnings("unchecked")
    public static <T> byte[] serialize(T obj) {
        Class<T> clazz = (Class<T>) obj.getClass();

        Schema<T> schema = getSchema(clazz);
        byte[] byteArray = new byte[0];
        try {
            byteArray = ProtostuffIOUtil.toByteArray(obj, schema, buffer);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            buffer.clear();
        }
        return byteArray;
    }

    /**
     * 反序列化方法,把字节数组反序列化成指定Class类型
     */
    @SuppressWarnings("unchecked")
    public static <T> T deserialize(byte[] data, Class<T> clazz) {
        Schema<T> schema = getSchema(clazz);
        T obj = schema.newMessage();
        ProtostuffIOUtil.mergeFrom(data, obj, schema);
        return obj;
    }


    @SuppressWarnings("unchecked")
    private static <T> Schema<T> getSchema(Class<T> clazz) {
        Schema<T> schema = (Schema<T>) schemaCache.get(clazz);
        if (schema == null) {
            schema = RuntimeSchema.getSchema(clazz);
            if (schema != null) {
                schemaCache.put(clazz, schema);
            }
        }
        return schema;
    }

}

测试类

package com.zhz.test.serialization.protostuff;

import com.zhz.test.serialization.entity.Address;
import com.zhz.test.serialization.entity.ProtoStuffStudent;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * @author zhouhengzhe
 */
@SpringBootTest
public class TestProtoStuff {

    @Test
    public void test() {
        ProtoStuffStudent stuffStudent = ProtoStuffStudent
                .builder()
                .age(3)
                .name("lance")
                .schoolName("bjut")
                .studentNo("2019060544")
                .address(Address
                        .builder()
                        .city("hunan")
                        .province("address")
                        .build())
                .build();

        //序列化
        byte[] serialize = ProtobufUtils.serialize(stuffStudent);
        System.out.println(serialize.length);
        //反序列化
        ProtoStuffStudent deserialize = ProtobufUtils.deserialize(serialize, ProtoStuffStudent.class);
        System.out.println(deserialize);
    }
}

打个号外

本人新搞的个人项目,有意者可到 DDD用户中台 这里购买

可以学习到的体系

  • 项目完全从0到1开始架构,包含前端,后端,架构,服务器,技术管理相关运维知识!

    • 最佳包名设计,项目分层
  • 破冰CRUD,手撕中间件!

    • 基于MybatisPlus封装属于自己的DDD ORM框架

    • 基于Easyexcel封装属于自己的导入导出组件

    • oss对象存储脚手架(阿里云,minio,腾讯云,七牛云等)

    • 邮件脚手架

    • completefuture脚手架

    • redis脚手架

    • xxl-job脚手架

    • 短信脚手架

    • 常用工具类等

  • 传统MVC代码架构弊端的解决方案

    • DDD+CQRS+ES最难架构
  • 结合实际代码的业务场景

    • 多租户单点登录中心

    • 用户中台

    • 消息中心

    • 配置中心

    • 监控设计

  • 程序员的职业规划,人生规划

    • 打工永远没有出路!

    • 打破程序员的35岁魔咒

    • 技术带给你的优势和竞争力【启发】

    • 万物互联网的淘金之路!

技术以外的赚钱路子

可以一起沟通

具体的文章目录

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

购买链接

DDD用户中台

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2180714.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#多线程数据同步的几种方式(不同的锁)

无锁 多个关联数据无法完整获取修改 internal class Program{static void Main(string[] args){Console.WriteLine("Hello, World!");ThreadPool.QueueUserWorkItem(Thread1);ThreadPool.QueueUserWorkItem(Thread2);ThreadPool.QueueUserWorkItem(Thread3);Console…

SpringBoot框架在墙绘产品展示中的运用

4 系统设计 墙绘产品展示交易平台的设计方案比如功能框架的设计&#xff0c;比如数据库的设计的好坏也就决定了该系统在开发层面是否高效&#xff0c;以及在系统维护层面是否容易维护和升级&#xff0c;因为在系统实现阶段是需要考虑用户的所有需求&#xff0c;要是在设计阶段没…

linux查看进程所在的目录

在Linux系统中&#xff0c;查看一个进程所在的目录&#xff08;即该进程的可执行文件所在的目录&#xff09;可以通过多种方式实现。 以下是查找进程的可执行文件路径的方法&#xff1a; 使用ls -l /proc/[pid]/cwd 你可以通过查看/proc/[pid]/cwd的符号链接来找到进程的可执…

UE5蓝图实战:动态墙上挖坑与自定义坑尺寸

在Unreal Engine 5.3中&#xff0c;我利用蓝图系统开发了一个创新的挖坑Demo&#xff0c;该Demo展示了如何在实时环境中动态地在墙体上挖坑&#xff0c;并允许用户自定义坑的大小。这一过程得益于UE5官方提供的Geometry Script插件&#xff0c;该插件通过蓝图接口实现了强大的网…

sql-labs:42~65

less42&#xff08;单引号闭合、报错回显&#xff09; login_useradmin login_password123 and if(11,sleep(2),1) # # 单引号闭合 ​ login_useradmin login_password123and updatexml(1,concat(0x7e,database(),0x7e),1)# # 报错回显…

端模一体,猎豹移动对大模型机器人发展路径清晰

今年世界机器人大会刚刚收官不久&#xff0c;接咖啡、拿苹果、摊煎饼……人形机器人在这届大会上备受关注&#xff0c;厂商们编排“整活”&#xff0c;展位几乎水泄不通。 自从AI大模型开始全面改变市场开始&#xff0c;关于机器人的方向性争论就不绝于耳&#xff0c;就在最近的…

北京中实新材料:携手知名建筑企业,共筑重大工程辉煌篇章

近年来,北京中实新材料有限责任公司(以下简称“北京中实”)凭借其卓越的产品质量、专业的技术服务和良好的市场信誉,积极参与了一系列重大工程项目的建设,与多家知名建筑企业建立了长期稳定的合作关系,共同书写了城市发展的辉煌篇章。 深耕行业,铸就品质基石 自成立以来,北京中…

Python查漏补缺

1.冒泡排序 时间复杂度O&#xff08;n^2) 选择、插入都是 def bubble(data, reverse):for i in range(len(data)-1):for j in range(len(data)-i-1):if data[j] > data[j1]:data[j], data[j1] data[j1], data[j]if reverse:data.reverse()return data 2.快速排序 时间…

《OpenCV 计算机视觉》—— 图像拼接

还未写完&#xff01;&#xff01;&#xff01; 下面是两张需要拼接的图片 完整代码&#xff1a; import cv2 import numpy as np import sysdef cv_show(name, img):cv2.imshow(name, img)cv2.waitKey(0)def detectAndDescribe(image):gray cv2.cvtColor(image, cv2.COLOR_…

mobile_aloha训练过程中pycharm编辑器遇到的问题记录

目前在研究mobile aloha的训练算法部分&#xff0c;运行文件为imitate_episodes.py&#xff0c;对应指令&#xff1a; # To train ACT: python3 imitate_episodes.py --task_name mobile_imu --ckpt_dir /home/song/hjx/aloha/mobile-aloha_multi-sensor/ckpt/mobile_imu --pol…

Mac屏蔽系统更新,取出红点标记如果解锁hosts文件

引言&#xff1a;关闭系统更新&#xff0c;首先应该在系统偏好设置---软件更新---去掉自动更新的选项。即使如此&#xff0c;系统仍然进行macOS系统和自带safari等软件的检测更新&#xff0c;并图标右上角红点点标记提醒我们更新&#xff0c;那我们如果彻底屏蔽更新呢&#xff…

计算机毕业设计 基于爬虫与文本挖掘的网络舆情监控系统的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

网站建设公司如何选?2024专业网站建设公司哪家好TOP3

要找一家靠谱的网站建设公司&#xff0c;可以根据以下五点判断&#xff1a; 1.企业的工商信息 企业有多少人、什么时候成立的、成立资金是多少、是否有违约记录这些都可以在查企业的那种app里可以看到&#xff0c;去查的时候一定要仔细甄别&#xff0c;别最后找了一家皮包公司…

HarmonyOS/OpenHarmony Audio 实现音频录制及播放功能

关键词&#xff1a;audio、音频录制、音频播放、权限申请、文件管理 在app的开发过程中时常会遇见一些需要播放一段音频或进行语音录制的场景&#xff0c;那么本期将介绍如何利用鸿蒙 audio 模块实现音频写入和播放的功能。本次依赖的是 ohos.multimedia.audio 音频管理模块&am…

基于Python大数据可视化的短视频推荐系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

大模型压缩3种方式;模型大小的计算;知识蒸馏:利用教师的输入输出,训练调整学生的小模型

目录 大模型压缩3种方式 模型大小的计算 知识蒸馏:利用教师的输入输出,训练调整学生的小模型 最终学生学习多个教师的知识,学生强大 大模型压缩3种方式 模型大小的计算 知识蒸馏:利用教师的输入输出,训练调整学生的小模型

商务英语口语柯桥外语学习|ass是“屁股”,save是“救”,那 save my ass是什么意思?

有些人活着&#xff0c;屁股却已经“死”了 工作工作&#xff0c;上工就“坐”&#xff0c;“久坐”几乎是无法避免的事情&#xff0c;但你知道吗&#xff0c;长期久坐可能会患上死臀综合症&#xff08;Dormant Butt Syndrome&#xff09;&#xff01; 如果你坐久了就觉得屁股痛…

imagickd写shell的技术学习

前言 没想到吧哥们&#xff0c;imagickd也能写shell&#xff0c;真是学到了不少&#xff0c;下面会具体分析是如何写shell的 基础知识 Imagick类 参考官方手册https://www.php.net/manual/zh/class.imagick.php 重点关注他的构造方法 (PECL imagick 2, PECL imagick 3) …

基于vue框架的大学生兼职平台r8x19(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;企业,用户,兼职信息,报名记录,岗位类型,专业,取消记录,评价记录 开题报告内容 基于Vue框架的大学生兼职平台开题报告 一、开题报告名称 基于Vue框架的大学生兼职平台 二、研究背景与意义 2.1 研究背景 随着高等教育的普及和就业市…

https访问报错:net::ERR_CERT_DATE_INVALLD

目录 简介异常排查原因解决补充 简介 访问https资源出现报错 异常 排查 将地址拿到浏览器进行访问&#xff0c;可以很清晰的看到出现该问题的原因 原因 1、SSL证书已过期 2、服务器日期不准&#xff0c;不在证书有效期 解决 1、重新申请SSL证书&#xff0c;并配置 2、校正…