KryoSerializer.java 2.5 KB
Newer Older
S
shuang.kou 已提交
1 2 3 4 5
package github.javaguide.serialize.kyro;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
S
shuang.kou 已提交
6 7
import github.javaguide.remoting.dto.RpcRequest;
import github.javaguide.remoting.dto.RpcResponse;
S
shuang.kou 已提交
8 9
import github.javaguide.exception.SerializeException;
import github.javaguide.serialize.Serializer;
10
import lombok.extern.slf4j.Slf4j;
S
shuang.kou 已提交
11 12 13 14 15

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

/**
16 17
 * Kryo序列化类,Kryo序列化效率很高,但是只兼容 Java 语言
 *
S
shuang.kou 已提交
18 19 20
 * @author shuang.kou
 * @createTime 2020年05月13日 19:29:00
 */
21
@Slf4j
S
shuang.kou 已提交
22 23 24 25 26 27
public class KryoSerializer implements Serializer {

    /**
     * 由于 Kryo 不是线程安全的。每个线程都应该有自己的 Kryo,Input 和 Output 实例。
     * 所以,使用 ThreadLocal 存放 Kryo 对象
     */
28
    private final ThreadLocal<Kryo> kryoThreadLocal = ThreadLocal.withInitial(() -> {
S
shuang.kou 已提交
29 30 31
        Kryo kryo = new Kryo();
        kryo.register(RpcResponse.class);
        kryo.register(RpcRequest.class);
32 33
        kryo.setReferences(true); //默认值为true,是否关闭注册行为,关闭之后可能存在序列化问题,一般推荐设置为 true
        kryo.setRegistrationRequired(false); //默认值为false,是否关闭循环引用,可以提高性能,但是一般不推荐设置为 true
S
shuang.kou 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
        return kryo;
    });

    @Override
    public byte[] serialize(Object obj) {
        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
             Output output = new Output(byteArrayOutputStream)) {
            Kryo kryo = kryoThreadLocal.get();
            // Object->byte:将对象序列化为byte数组
            kryo.writeObject(output, obj);
            kryoThreadLocal.remove();
            return output.toBytes();
        } catch (Exception e) {
            throw new SerializeException("序列化失败");
        }
    }

    @Override
    public <T> T deserialize(byte[] bytes, Class<T> clazz) {
        try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
             Input input = new Input(byteArrayInputStream)) {
            Kryo kryo = kryoThreadLocal.get();
            // byte->Object:从byte数组中反序列化出对对象
            Object o = kryo.readObject(input, clazz);
            kryoThreadLocal.remove();
            return clazz.cast(o);
        } catch (Exception e) {
            throw new SerializeException("反序列化失败");
        }
    }

}