老王讲自制RPC框架.(四.序列化与反序列化)

#(序列化)

在实际的框架中,真正影响效率的就是数据的传输方式,以及传输的准备,或者说是tcp与http,序列化.当然要想提高整个框架的效率,需要采用一种高效的序列化

框架比如流行的protostuff.总结一些有点如下:

(1).Java序列化对象时不需要通过属性的get set方法或其它无关序列化内部定义的方法(比如readObject,writeObject是内置的序列化方法),序列化也不需要get set方法

支持,反序列化是构造对象的一种手段。

(2).Java序列化时类型必须完全匹配(全路径类名+序列化id)。

(3).Protostuff反序列化时并不要求类型匹配,比如包名、类名甚至是字段名,它仅仅需要序列化类型A 和反序列化类型B 的字段类型可转换(比如int可以转换为long)即可

#(demo)

先声明两个po类,不需要保证类的名称,以及属性的名,如下:

public class PersonA {
    private String name;
    private int age;
    .....
}


public class PersonB {
    private String nameB;
    private int ageB;
    .....
}

下面再随便写一个方法跑起来:

public static void test1() {
        PersonA personA = new PersonA("A", 12);
        byte[] arr = ProtoStuffUtil.serialize(personA);
        PersonB personB = ProtoStuffUtil.deserialize(arr, PersonB.class);
    }

在这个过程中,我们首先将A序列化成二进制码,然后又将二进制的A反序列化成B对象。

来看一下util的实现:

public class ProtoStuffUtil {
    public static <T> byte[] serialize(T obj) {
        if (obj == null) {
            throw new RuntimeException("序列化对象(" + obj + ")!");
        }
        //主题,只要实现了一个主题就可以被序列化和反序列化
        Schema<T> schema = (Schema<T>) RuntimeSchema.getSchema(obj.getClass());
        LinkedBuffer buffer = LinkedBuffer.allocate(1024 * 1024);
        byte[] protostuff = null;
        try {
            protostuff = ProtostuffIOUtil.toByteArray(obj, schema, buffer);
        } catch (Exception e) {
            throw new RuntimeException("序列化(" + obj.getClass() + ")对象(" + obj + ")发生异常!", e);
        } finally {
            buffer.clear();
        }
        return protostuff;
    }

    public static <T> T deserialize(byte[] paramArrayOfByte, Class<T> targetClass) {
        if (paramArrayOfByte == null || paramArrayOfByte.length == 0) {
            throw new RuntimeException("反序列化对象发生异常,byte序列为空!");
        }
        T instance = null;
        try {
            instance = targetClass.newInstance();
        } catch (IllegalAccessException e) {
            throw new RuntimeException("反序列化过程中依据类型创建对象失败!", e);
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        Schema<T> schema = RuntimeSchema.getSchema(targetClass);
        ProtostuffIOUtil.mergeFrom(paramArrayOfByte, instance, schema);
        return instance;
    }
}

使用起来就是这么简单.

最后献上管网地址一枚:http://www.protostuff.io/  

posted @ 2016-11-20 00:34  nasjjsadkef  阅读(1620)  评论(0编辑  收藏  举报