package com.yiidata.intergration.common.cache.serde;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.util.Pool;
import com.google.common.primitives.Ints;
import com.google.gson.Gson;
import org.apache.commons.lang.StringUtils;
import java.io.ByteArrayInputStream;
import java.nio.charset.Charset;
import java.util.Arrays;
/**
*
* Kryo 序列化
*
*
*
* Created by zhenqin.
* User: zhenqin
* Date: 2022/5/30
* Time: 下午4:41
* Vendor: yiidata.com
*
*
*
* @author zhenqin
*/
public class KryoFixSerializer implements Serializer {
// Pool constructor arguments: thread safe, soft references, maximum capacity
final Pool kryoPool = new Pool(true, false, 8) {
protected Kryo create () {
Kryo kryo = new Kryo();
// Kryo 配置
return kryo;
}
};
private final StringSerializer serializer;
public KryoFixSerializer() {
serializer = new StringSerializer();
}
public KryoFixSerializer(String charset) {
this.serializer = new StringSerializer(Charset.forName(charset));
}
public KryoFixSerializer(StringSerializer serializer) {
this.serializer = serializer;
}
@Override
public byte[] serialize(T o) {
// 获取池中的Kryo对象
Kryo kryo = kryoPool.obtain();
try {
String clazz = o.getClass().getName();
byte[] classString = clazz.getBytes(serializer.getCharset());
int length = classString.length;
byte[] head = Ints.toByteArray(length);
// 写入数据缓冲区
Output opt = new Output(1024, -1);
kryo.writeClassAndObject(opt, o);
opt.flush();
byte[] body = opt.getBuffer();
byte[] bytes = new byte[head.length + length + body.length];
System.arraycopy(head, 0, bytes, 0, head.length);
System.arraycopy(classString, 0, bytes, head.length, classString.length);
System.arraycopy(body, 0, bytes, head.length + length, body.length);
return bytes;
} finally {
// 将kryo对象归还到池中
kryoPool.free(kryo);
}
}
@Override
public T deserialize(byte[] bytes) {
// 获取池中的Kryo对象
Kryo kryo = kryoPool.obtain();
try {
// 前面 4 个字节是头,代表 类名 的长度
byte[] head = new byte[4];
System.arraycopy(bytes, 0, head, 0, head.length);
// 类名称,全名
int length = Ints.fromBytes(bytes[0], bytes[1], bytes[2], bytes[3]);
String classString = new String(bytes, 4, length);
// 后面是实际的序列化数据
byte[] data = new byte[bytes.length - length - 4];
System.arraycopy(bytes, length + 4, data, 0, data.length);
return deserialize(kryo, data, (Class) Class.forName(classString));
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e);
} finally {
// 将kryo对象归还到池中
kryoPool.free(kryo);
}
}
public T deserialize(Kryo kryo, byte[] bytes, Class clazz) {
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
Input input = new Input(in);
return kryo.readObject(input, clazz);
}
}