美文网首页简更Java 杂谈想法
基于Protostuff的序列化与反序列化

基于Protostuff的序列化与反序列化

作者: 日更专用小马甲 | 来源:发表于2019-03-17 13:56 被阅读1次

    这是《手写RPC框架,我学会了什么?》系列的第05篇

    上一篇 提到了protobuf。其实参考 官网 很快上手做了一个demo,但是跟之前写的RPC框架集成的不是很好(主要卡在Client的部分)。在搜索资料的过程中看到了一个第三方库:protostuff。

    对比

    易用性 方面先做一个简单的对比:

    • 原生的protobuf,需要手写.proto文件(也就是定义协议),再通过编译生成相应的Java代码,再通过相应的API完成序列化和反序列化。

    • 编译生成的Java代码有上千行,而且对于框架有一点的“入侵性”。

    • protostuff对于POJO支持的很好。
      (关于实现原理这里先再埋个坑,猜测是定义了一个通用的协议)

    实现

    基于protostuff实现一个序列化和反序列化的工具,代替之前Java原生的序列化。
    (其实只是对ProtostuffIOUtil做一个简单的封装)

    /**
     * 序列化和反序列化工具类
     *
     * @author nathan
     * @date 2019/3/17
     */
    public class SerializingUtil {
    
        /**
         * 将目标类序列化为byte数组
         *
         * @param source
         * @param <T>
         * @return
         */
        public static <T> byte[] serialize(T source) {
            RuntimeSchema<T> schema;
            LinkedBuffer buffer = null;
            byte[] result;
            try {
                schema = RuntimeSchema.createFrom((Class<T>) source.getClass());
                buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
                result = ProtostuffIOUtil.toByteArray(source, schema, buffer);
            } catch (Exception e) {
                throw new RuntimeException("serialize exception");
            } finally {
                if (buffer != null) {
                    buffer.clear();
                }
            }
    
            return result;
        }
    
        /**
         * 将byte数组反序列化为目标类
         *
         * @param source
         * @param typeClass
         * @param <T>
         * @return
         */
        public static <T> T deserialize(byte[] source, Class<T> typeClass) {
            RuntimeSchema<T> schema;
            T newInstance;
            try {
                schema = RuntimeSchema.createFrom(typeClass);
                newInstance = typeClass.newInstance();
                ProtostuffIOUtil.mergeFrom(source, newInstance, schema);
            } catch (Exception e) {
                throw new RuntimeException("deserialize exception");
            }
    
            return newInstance;
        }
    }
    

    测试

    再用testng写个测试用例验证下。

    /**
     * 序列化和反序列化工具测试类
     *
     * @author nathan
     * @date 2019/3/17
     */
    public class SerializingUtilTest {
    
        @Test
        public void test() {
            String expect = "hello, world.";
            byte[] serialized = SerializingUtil.serialize(expect);
            Assert.assertEquals(SerializingUtil.deserialize(serialized, String.class), expect);
        }
    }
    
    

    Maven依赖

    <dependency>
        <groupId>com.dyuproject.protostuff</groupId>
        <artifactId>protostuff-core</artifactId>
        <version>1.0.7</version>
    </dependency>
    
    <dependency>
        <groupId>com.dyuproject.protostuff</groupId>
        <artifactId>protostuff-runtime</artifactId>
        <version>1.0.7</version>
    </dependency>
    

    相关文章

      网友评论

        本文标题:基于Protostuff的序列化与反序列化

        本文链接:https://www.haomeiwen.com/subject/zkoymqtx.html