Protostuff序列化

来源:互联网 发布:数据透视表是什么意思 编辑:程序博客网 时间:2024/06/08 07:02

这几天在看rpc框架的东西,一哥们写的轻量级rpc框架(http://my.oschina.net/huangyong/blog/361751?fromerr=NpC3phqY)实现,写的rpc很不错,就跟着撸了遍代码,里面用到的序列化工具是protostuff,之前我们项目供应商接口用的xml,没用过protostuff,拿过来研究下,写个demo示例,以后再需要的话,也可以拿过来用。

常用的序列化基本是xml,protobuf,protostuff,xml用起来简单方便,顺手就用,但是序列化/反序列化的性能不行,protobuf,Google出品,性能比xml肯定好,用于不同语言,不同平台的交互,需要预编译,用起来麻烦,改的东西都要编译下,感觉不适合数据结构经常变动,后来就来了protostuff,无需预编译,就可以对javabean进行序列化和反序列化,性能更好。

上代码,添加maven依赖:

<!-- Protostuff --><dependency>    <groupId>com.dyuproject.protostuff</groupId>    <artifactId>protostuff-core</artifactId>    <version>1.0.8</version></dependency><dependency>    <groupId>com.dyuproject.protostuff</groupId>    <artifactId>protostuff-runtime</artifactId>    <version>1.0.8</version></dependency><!-- Objenesis --><dependency>    <groupId>org.objenesis</groupId>    <artifactId>objenesis</artifactId>    <version>2.1</version></dependency>

ps:一般反射实例化java类的时候,newInstance如果java类没有默认构造函数,肯定不行,而objenesis用来对实例化java类,无需默认构造函数,官网:http://objenesis.org/tutorial.html,用起来很简单

SerializationUtils,序列化工具类,上面那个哥们rpc里面用的:

import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import org.objenesis.Objenesis;import org.objenesis.ObjenesisStd;import com.dyuproject.protostuff.LinkedBuffer;import com.dyuproject.protostuff.ProtostuffIOUtil;import com.dyuproject.protostuff.Schema;import com.dyuproject.protostuff.runtime.RuntimeSchema;public class SerializationUtils {    private static Map<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<Class<?>, Schema<?>>();        private static Objenesis objenesis = new ObjenesisStd(true);        private SerializationUtils(){    }        @SuppressWarnings("unchecked")    private static <T> Schema<T> getSchema(Class<T> cls){        Schema<T> schema = (Schema<T>)cachedSchema.get(cls);        if(schema == null){            schema = RuntimeSchema.createFrom(cls);            if(schema != null){                cachedSchema.put(cls, schema);            }        }        return schema;    }        @SuppressWarnings("unchecked")    public static <T> byte[] serializer(T obj){        Class<T> cls = (Class<T>) obj.getClass();        LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);        try{            Schema<T> schema = getSchema(cls);            return ProtostuffIOUtil.toByteArray(obj, schema, buffer);        }catch (Exception e) {            throw new IllegalStateException(e.getMessage(), e);        }finally{            buffer.clear();        }    }        public static <T> T deserializer(byte[] data, Class<T>cls){        try{            T message = (T)objenesis.newInstance(cls);            Schema<T> schema = getSchema(cls);            ProtostuffIOUtil.mergeFrom(data, message, schema);            return message;        }catch (Exception e) {            throw new IllegalStateException(e.getMessage(), e);        }    }}

下面是几个javabean

public class OrderInfo {    /**     * 订单流水     */    private String orderNo;    /**     * 订单概要信息     */    private Map<String, Object> orderItem;    /**     * 订单扩展信息     */    private List<OrderExt> orderExts;        /**     * 收货信息     */    private DelieryAddress address;    //getter,setter,toString方法

public class OrderExt {    /**     * 订单流水     */    private String orderNo;    /**     * 商品编码     */    private String goodsNo;        //getter,setter,toString方法

public class DelieryAddress {    /**     * 收货地址     */    private String address;    /**     * 收货人     */    private String consigneeName;    /**     * 送达时间     */    private Date expectTime;        //getter,setter,toString方法

测试类:

public class ProtostuffTest {    public static void main(String[] args) {        OrderInfo oldOrder = createOrder();        System.out.println(oldOrder);                byte[] orderinfo = SerializationUtils.serializer(oldOrder);                OrderInfo neOrder = SerializationUtils.deserializer(orderinfo, OrderInfo.class);                System.out.println(neOrder);        System.out.println(neOrder.getOrderNo() == null ? "y" : "n");    }        private static OrderInfo createOrder(){        OrderInfo orderInfo = new OrderInfo();        DelieryAddress delieryAddress = new DelieryAddress();        List<OrderExt> orderExts = new LinkedList<OrderExt>();                for(int i=0; i<2; i++){            OrderExt orderExt = new OrderExt();            orderExt.setGoodsNo("343434");            orderExt.setOrderNo("12345");            orderExts.add(orderExt);        }                delieryAddress.setAddress("江苏南京");        delieryAddress.setConsigneeName("熊猫");        delieryAddress.setExpectTime(new Date());                Map<String, Object> orderItem = new HashMap<String, Object>();        orderItem.put("google","google.com");        orderItem.put("baidu", "baidu.com");                orderInfo.setOrderItem(orderItem);        orderInfo.setAddress(delieryAddress);        orderInfo.setOrderExts(orderExts);                return orderInfo;    }}

主要测试javabean字段里面null/string/list/map或其他javabean做为参数,看看是否能够正确序列化和反序列。

结果完全没问题:



参考:

http://my.oschina.net/huangyong/blog/361751?fromerr=NpC3phqY

http://www.cnblogs.com/xiaoMzjm/p/4555209.html 对xml,protobuf,protostuff的序列化/反序列性能做了一些对比测试

0 0
原创粉丝点击