Fork me on GitHub

Java序列化之ProtoStuff

知识点:

  1. ProtoStuff 是将结构数据转为字节流进行序列化的,优点是占用空间小,速度快,缺点是可读性差。
  2. ProtoStuff 是基于 ProtoBuf 发展而来的。

本文不讲那么多背景,直接上代码:

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

public class ProtostuffRedisSerializer implements RedisSerializer<Object> {
    private static final Schema<ObjectWrapper> SCHEMA = RuntimeSchema.getSchema(ObjectWrapper.class);

    @Override
    public byte[] serialize(Object o) throws SerializationException {
        LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
        byte[] bytes;
        try {
            bytes = ProtostuffIOUtil.toByteArray(new ObjectWrapper(o), SCHEMA, buffer);
        } finally {
            buffer.clear();
        }
        return bytes;
    }

    @Override
    public Object deserialize(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        ObjectWrapper wrapper = new ObjectWrapper();
        ProtostuffIOUtil.mergeFrom(bytes, wrapper, SCHEMA);
        return wrapper.getObject();
    }

    @Override
    public boolean canSerialize(Class<?> type) {
        return false;
    }

    @Override
    public Class<?> getTargetType() {
        return null;
    }

    public static class ObjectWrapper {
        private Object object;

        public ObjectWrapper() {
        }

        public ObjectWrapper(Object object) {
            this.object = object;
        }

        public Object getObject() {
            return object;
        }

        public void setObject(Object object) {
            this.object = object;
        }
    }
}


在RedisTemplate上使用:

    private static final String PROTOSTUFF_REDIS_TEMPLATE = "protostuffRedisTemplate";

    @Bean(name = PROTOSTUFF_REDIS_TEMPLATE)
    public RedisTemplate<String, Object> protostuffRedisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        template.setKeySerializer(redisSerializer);
        template.setHashKeySerializer(redisSerializer);

        ProtostuffRedisSerializer protostuffRedisSerializer = new ProtostuffRedisSerializer();
        template.setValueSerializer(protostuffRedisSerializer);
        template.setHashValueSerializer(protostuffRedisSerializer);

        template.afterPropertiesSet();
        return template;
    }

参考:

  1. java序列化/反序列化之xstream、protobuf、protostuff 的比较与使用例子
  2. Protobuf vs. Protostuff:性能、易用性和适用场景分析
posted @ 2024-08-05 17:55  竹根七  阅读(12)  评论(0编辑  收藏  举报