KryoFixSerializer.java 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package com.yiidata.intergration.common.cache.serde;
  2. import com.esotericsoftware.kryo.Kryo;
  3. import com.esotericsoftware.kryo.io.Input;
  4. import com.esotericsoftware.kryo.io.Output;
  5. import com.esotericsoftware.kryo.util.Pool;
  6. import com.google.common.primitives.Ints;
  7. import com.google.gson.Gson;
  8. import org.apache.commons.lang.StringUtils;
  9. import java.io.ByteArrayInputStream;
  10. import java.nio.charset.Charset;
  11. import java.util.Arrays;
  12. /**
  13. *
  14. * Kryo 序列化
  15. *
  16. * <pre>
  17. *
  18. * Created by zhenqin.
  19. * User: zhenqin
  20. * Date: 2022/5/30
  21. * Time: 下午4:41
  22. * Vendor: yiidata.com
  23. *
  24. * </pre>
  25. *
  26. * @author zhenqin
  27. */
  28. public class KryoFixSerializer<T> implements Serializer<T> {
  29. // Pool constructor arguments: thread safe, soft references, maximum capacity
  30. final Pool<Kryo> kryoPool = new Pool<Kryo>(true, false, 8) {
  31. protected Kryo create () {
  32. Kryo kryo = new Kryo();
  33. // Kryo 配置
  34. return kryo;
  35. }
  36. };
  37. private final StringSerializer serializer;
  38. public KryoFixSerializer() {
  39. serializer = new StringSerializer();
  40. }
  41. public KryoFixSerializer(String charset) {
  42. this.serializer = new StringSerializer(Charset.forName(charset));
  43. }
  44. public KryoFixSerializer(StringSerializer serializer) {
  45. this.serializer = serializer;
  46. }
  47. @Override
  48. public byte[] serialize(T o) {
  49. // 获取池中的Kryo对象
  50. Kryo kryo = kryoPool.obtain();
  51. try {
  52. String clazz = o.getClass().getName();
  53. byte[] classString = clazz.getBytes(serializer.getCharset());
  54. int length = classString.length;
  55. byte[] head = Ints.toByteArray(length);
  56. // 写入数据缓冲区
  57. Output opt = new Output(1024, -1);
  58. kryo.writeClassAndObject(opt, o);
  59. opt.flush();
  60. byte[] body = opt.getBuffer();
  61. byte[] bytes = new byte[head.length + length + body.length];
  62. System.arraycopy(head, 0, bytes, 0, head.length);
  63. System.arraycopy(classString, 0, bytes, head.length, classString.length);
  64. System.arraycopy(body, 0, bytes, head.length + length, body.length);
  65. return bytes;
  66. } finally {
  67. // 将kryo对象归还到池中
  68. kryoPool.free(kryo);
  69. }
  70. }
  71. @Override
  72. public T deserialize(byte[] bytes) {
  73. // 获取池中的Kryo对象
  74. Kryo kryo = kryoPool.obtain();
  75. try {
  76. // 前面 4 个字节是头,代表 类名 的长度
  77. byte[] head = new byte[4];
  78. System.arraycopy(bytes, 0, head, 0, head.length);
  79. // 类名称,全名
  80. int length = Ints.fromBytes(bytes[0], bytes[1], bytes[2], bytes[3]);
  81. String classString = new String(bytes, 4, length);
  82. // 后面是实际的序列化数据
  83. byte[] data = new byte[bytes.length - length - 4];
  84. System.arraycopy(bytes, length + 4, data, 0, data.length);
  85. return deserialize(kryo, data, (Class<T>) Class.forName(classString));
  86. } catch (ClassNotFoundException e) {
  87. throw new IllegalStateException(e);
  88. } finally {
  89. // 将kryo对象归还到池中
  90. kryoPool.free(kryo);
  91. }
  92. }
  93. public T deserialize(Kryo kryo, byte[] bytes, Class<T> clazz) {
  94. ByteArrayInputStream in = new ByteArrayInputStream(bytes);
  95. Input input = new Input(in);
  96. return kryo.readObject(input, clazz);
  97. }
  98. }