JSON序列化器存在的问题:反序列化的是对象中有Object类型的属性,反序列化会出错Kryo是一个快速高效的java对象序列化器,特点就是高性能、高效、易用。它是基于字节的序列化,对空间利用率高,在网络传输时可以减小体积,并且在序列化时记录属性对象的类型信息,因此在反序列化时不会出现类型错误的情况。
实现过程如下: 一、引入依赖
Kryo依赖
二、使用Kryo进行序列化 1.向CommonSerializer添加Kryo序列化com.esotericsoftware kryo 4.0.2
package com.t598.core.serializer;
public interface CommonSerializer {
Integer KRYO_SERIALIZER = 0;
Integer JSON_SERIALIZER = 1;
Integer HESSIAN_SERIALIZER = 2;
Integer PROTOBUF_SERIALIZER = 3;
Integer DEFAULT_SERIALIZER = KRYO_SERIALIZER;
byte[] serializer(Object object);
Object deserialize(byte[] bytes, Class> clazz) throws Exception;
int getCode();
static CommonSerializer getByte(int code) {
switch (code) {
case 0:
return new KryoSerializer();
case 1:
return new JsonSerializer();
default:
return null;
}
}
}
2.实现KryoSerializer()
package com.t598.core.serializer;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.t598.common.entity.RpcRequest;
import com.t598.common.entity.RpcResponse;
import com.t598.common.enumeration.SerializerCode;
import com.t598.common.exception.SerializeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class KryoSerializer implements CommonSerializer{
private static final Logger logger = LoggerFactory.getLogger(KryoSerializer.class);
private static final ThreadLocal kryoThreadLocal = ThreadLocal.withInitial(() -> {
Kryo kryo = new Kryo();
// 注册序列化和反序列化类
kryo.register(RpcResponse.class);
kryo.register(RpcRequest.class);
// 设置true如果出现多次则是序列化一次
kryo.setReferences(true);
// 未注册的类也可以进行反序列化
kryo.setRegistrationRequired(false);
return kryo;
});
@Override
public byte[] serializer(Object object) {
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 序列化时先创建一个output对象,然后使用writeObject将object对象写入output中,在调用getBytes即可获得对象的字节数组。
Output output = new Output(byteArrayOutputStream)) {
Kryo kryo = kryoThreadLocal.get();
kryo.writeObject(output, object);
kryoThreadLocal.remove();
return output.toBytes();
} catch (IOException e) {
logger.error("序列化时有错误发生:", e);
throw new SerializeException("序列化时有错误发生");
}
}
@Override
public Object deserialize(byte[] bytes, Class> clazz) throws Exception {
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
Input input = new Input(byteArrayInputStream)) {
// 反序列化则只需要传入对象的类型,而不需要传入对象的每一个属性的类型信息
Kryo kryo = kryoThreadLocal.get();
Object o = kryo.readObject(input, clazz);
kryoThreadLocal.remove();
return o;
}
}
@Override
public int getCode() {
return SerializerCode.valueOf("KRYO").getCode();
}
}



