背景

最近在做项目的时候需要使用持久化功能,1.0版本中使用的akka自带的持久化功能,使用的是akka persist支持的redis插件,在使用的过程中踩了一些坑。因此,在而2.0版本中考虑自己往redis中持久化。要做持久化,必须考虑对象的序列化问题。序列化的方法很多,可以使用java自带的序列化机制,但是时间效率不太好。因此在kryo和protobuffer之间徘徊。因为以前使用过grpc,需要手动编写proto文件,然后利用插件生成代码,觉得很麻烦。但是通过搜索了解到还有一个protostuff不需要编写proto文件这个麻烦的步骤,并且效率还很好。因此,学习了下。

引入依赖

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

javaBean

编写需要序列化和反序列化的对象

public class User {

    private String name;

    private int age;

    public User(String name, int age) {
this.name = name;
this.age = age;
}
} public class Group { private String id; private String name; private List<User> users; public Group(String id, String name, List<User> users) {
this.id = id;
this.name = name;
this.users = users;
}
}

开发序列化和反序列化工具类

public class ProtostuffUtils {
/**
* 避免每次序列化都重新申请Buffer空间
*/
private static LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
/**
* 缓存Schema
*/
private static Map<Class<?>, Schema<?>> schemaCache = new ConcurrentHashMap<Class<?>, Schema<?>>(); /**
* 序列化方法,把指定对象序列化成字节数组
*
* @param obj
* @param <T>
* @return
*/
@SuppressWarnings("unchecked")
public static <T> byte[] serialize(T obj) {
Class<T> clazz = (Class<T>) obj.getClass();
Schema<T> schema = getSchema(clazz);
byte[] data;
try {
data = ProtostuffIOUtil.toByteArray(obj, schema, buffer);
} finally {
buffer.clear();
} return data;
} /**
* 反序列化方法,将字节数组反序列化成指定Class类型
*
* @param data
* @param clazz
* @param <T>
* @return
*/
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进行懒创建并缓存
//所以可以一直调用RuntimeSchema.getSchema(),这个方法是线程安全的
schema = RuntimeSchema.getSchema(clazz);
if (schema == null) {
schemaCache.put(clazz, schema);
}
} return schema;
} public static void main(String[] args){
final User user1 = new User("aaa",20);
final User user2 = new User("bbb",21);
List<User> users = new ArrayList<User>(){{add(user1);add(user2);}};
Group group = new Group("id_1","group1",users); byte[] bytes = ProtostuffUtils.serialize(group);
System.out.println("序列化后: " + bytes.length); Group group1 = ProtostuffUtils.deserialize(bytes,Group.class);
System.out.println("反序列化后: " + group1.getName()); }

运行结果如下:

序列化后: 32
反序列化后: group1

工具类参考博客:https://blog.csdn.net/oppo5630/article/details/80173520

protostuff的github地址:https://github.com/protostuff/protostuff

protostuff序列化使用的更多相关文章

  1. Protostuff序列化分析

    前言最近项目中需要将业务对象直接序列化,然后存数据库:考虑到序列化.反序列化的时间以及生产文件的大小觉得Protobuf是一个很好的选择,但是Protobuf有的问题就是需要有一个.proto的描述文 ...

  2. Protostuff序列化问题

    最近在开发中遇到一个Protostuff序列化问题,在这记录一下问题的根源:分析一下Protostuff序列化和反序列化原理:以及怎么样避免改bug. 1. 问题描述 有一个push业务用到了mq,m ...

  3. Protostuff序列化

    前言: Java序列化是Java技术体系当中的一个重要议题,序列化的意义在于信息的交换和存储,通常会和io.持久化.rmi技术有关(eg:一些orm框架会要求持久化的对象类型实现Serializabl ...

  4. Protostuff序列化工具类

    源代码 package org.wit.ff.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStre ...

  5. Protostuff序列化和反序列化

    序列化和反序列化是在应对网络编程最常遇到的问题之一. 序列化就是将Java Object转成byte[]:反序列化就是将byte[]转成Java Object. 这里不介绍JDK serializab ...

  6. java protostuff 序列化反序列化工具

    protostuff是由谷歌开发的一个非常优秀的序列化反序列化工具 maven导入包: <dependency> <groupId>io.protostuff</grou ...

  7. Protostuff序列化和反序列化使用说明

    原文:http://blog.csdn.net/zhglance/article/details/56017926 google原生的protobuffer使用起来相当麻烦,首先要写.proto文件, ...

  8. 通讯协议序列化解读(二) protostuff详解教程

    上一篇文章 通讯协议序列化解读(一):http://www.cnblogs.com/tohxyblog/p/8974641.html  前言:上一面文章我们介绍了java序列化,以及谷歌protobu ...

  9. java序列化/反序列化之xstream、protobuf、protostuff 的比较与使用例子

    目录 背景 测试 环境 工具 说明 结果 结论 xstream简单教程 准备 代码 protobuf简单教程 快速入门 下载.exe编译器 编写.proto文件 利用编译器编译.proto文件生成ja ...

随机推荐

  1. Oracle 学习---- 练习语法 循环( loop end loop; for ;while; if elsif end if )

    /*--set serveroutput on;declare mynum number(3) :=0; tip varchar2(10):='结果是 ';begin mynum:=10+100; d ...

  2. ZOJ 3606 Lazy Salesgirl ( 线段树 + 思路 )

    卖切糕的小女孩 http://www.cnblogs.com/wuyiqi/archive/2012/04/28/2474672.html #include <cstdio> #inclu ...

  3. HDU 4681 String 胡搞

    设串C的第一个字母在串A中出现的位置是stA, 串C的最后一个字母在串A中出现的位置是edA. 设串C的第一个字母在串B中出现的位置是stB, 串C的最后一个字母在串B中出现的位置是edB. 求出每一 ...

  4. PHP上传多文件

    知识点: 一.$_FILES数组 ①.$_FILES['filename']['name']上传文件原名 ②.$_FILES['filename']['tmp_name']上传成功后的缓存文件名 ③. ...

  5. group_load,weight_load,group_capacity, group_weight大致都是啥数值

    [ 113.180820] sgs->group_load:2039,sum_nr_running:2,sum_weighted_load:2039,sgs->group_capacity ...

  6. glibc内存泄露以及TCmalloc 简单分析

    最近开发一个私人程序时碰到了严重的内存问题,具体表现为:进程占用的内存会随着访问高峰不断上升,直到发生OOM被kill为止.我们使用valgrind等工具进行检查发现程序并无内存泄露,经过仔细调查我们 ...

  7. [codeforces934E]A Colourful Prospect

    [codeforces934E]A Colourful Prospect 试题描述 Firecrackers scare Nian the monster, but they're wayyyyy t ...

  8. [poj] 2074 Line of Sight || 直线相交求交点

    原题 给出一个房子(线段)的端点坐标,和一条路的两端坐标,给出一些障碍物(线段)的两端坐标.问在路上能看到完整房子的最大连续长度是多长. 将障碍物按左端点坐标排序,然后用房子的右端与障碍物的左端连线, ...

  9. BZOJ4894 天赋 【矩阵树定理】

    题目链接 BZOJ4894 题解 双倍经验P5297 题解 #include<iostream> #include<cstring> #include<cstdio> ...

  10. 平面ray trace的数据结构加速

    yy了一个数据结构.. 首先考虑到,平面ray trace对应的scene是planar graph with coordinates,特点是除端点外无相交. 我们考虑对所有端点建立kd-tree,注 ...