7-2 序列化集成ptotobuf

protostuff基于protobuf的序列化/反序列化,不需要编写.proto文件,方便使用。

针对kryo的序列化demo,使用protostuff。在producer和consumer的配置中分别配置自定义的ProtostuffSerializer和ProtostuffDerializer即可

注意使用protostuff序列化需要注意,序列化和反序列化的字段顺序问题。

1、引入依赖
<dependency>
    <groupId>io.protostuff</groupId>
    <artifactId>protostuff-runtime</artifactId>
    <version>1.5.9</version>
</dependency>
<dependency>
    <groupId>io.protostuff</groupId>
    <artifactId>protostuff-core</artifactId>
    <version>1.5.9</version>
</dependency>
2、序列化反序列化工具
package org.example.learn2.util;

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;
import org.objenesis.Objenesis;
import org.objenesis.ObjenesisStd;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @author maochao
 * @since 2019/7/8 18:00
 */
public class ProtostuffUtil {
    private static final Objenesis objenesis = new ObjenesisStd(true);
    private static final ConcurrentMap<Class<?>, Schema<?>> schemaCache = new ConcurrentHashMap<>();
    private static ThreadLocal<LinkedBuffer> bufferThreadLocal = ThreadLocal.withInitial(() -> LinkedBuffer.allocate());

    public static <T> byte[] serialize(T obj) {
        Schema<T> schema = getSchema((Class<T>)obj.getClass());
        // 默认分配512
        LinkedBuffer buf = bufferThreadLocal.get();
        try {
            // object->byte[]
            return ProtostuffIOUtil.toByteArray(obj, schema, buf);
        } finally {
            buf.clear();
        }
    }

    private  static<T> Schema<T> getSchema(Class<T> clazz) {
        //缓存,
        Schema<T> schema = (Schema<T>)schemaCache.get(clazz);
        if (schema == null) {
            // 把可序列化的字段封装到Schema
            Schema<T> newSchema = RuntimeSchema.createFrom(clazz);
            schema = (Schema<T>)schemaCache.putIfAbsent(clazz, newSchema);
            if (schema == null) {
                schema = newSchema;
            }
        }
        return schema;
    }

    public static <T> T deserialize(byte[] bytes, Class<T> clazz) {
        // clazz-->Object
        T object = objenesis.newInstance(clazz);
        Schema<T> schema = getSchema(clazz);
        ProtostuffIOUtil.mergeFrom(bytes, object, schema);
        return object;
    }

}
3、重建消息对象
package org.example.learn2.entity;

import com.esotericsoftware.kryo.DefaultSerializer;

import java.io.Serializable;
import java.util.List;

/**
 * 消息对象
 *
 * @author
 * @date 2019/6/15
 */

public class KafkaMessage implements Serializable {
    private String id;
    // 消息对象
    private Message message;
    // .....其他属性

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Message getMessage() {
        return message;
    }

    public void setMessage(Message message) {
        this.message = message;
    }

    public class Message implements Serializable {

        public Long getValue() {
            return value;
        }

        public void setValue(Long value) {
            this.value = value;
        }

        private Long value;
        // ....其他属性
    }

    public Message builder() {
        return new Message();
    }

}
4、序列化
package org.example.learn2.producer;

import org.apache.kafka.common.serialization.Serializer;
import org.example.learn2.util.ProtostuffUtil;

import java.util.Map;

/**
 * 
 * ProtostuffSerializer 编码器
 * 
 * @author maochao
 * @since 2019/7/8 17:58
 * 
 */
public class ProtostuffSerializer implements Serializer {

    @Override
    public void configure(Map configs, boolean isKey) {

    }

    @Override
    public byte[] serialize(String topic, Object data) {
        return ProtostuffUtil.serialize(data);
    }

    @Override
    public void close() {

    }
}
5、反序列化
package org.example.learn2.consumer;

import org.apache.kafka.common.serialization.Deserializer;
import org.example.learn2.entity.KafkaMessage;
import org.example.learn2.util.ProtostuffUtil;

import java.util.Map;

/**
 * @author maochao
 * @since 2019/7/8 19:29
 */
public class ProtostuffDerializer implements Deserializer {
    @Override
    public void configure(Map configs, boolean isKey) {

    }

    @Override
    public Object deserialize(String topic, byte[] data) {
        return ProtostuffUtil.deserialize(data, KafkaMessage.class);
    }

    @Override
    public void close() {

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值