基于Netty实现高性能通信程序之序列化与反序列化
1、序列化接口
1 package serializer.service; 2 3 /** 4 * 序列化接口 5 * 6 * @author liupengr 7 * @date 2020/2/12 18:17 8 */ 9 public interface Serializer { 10 11 /** 12 * 获取当前序列化类型 13 * 14 * @return 15 */ 16 SerializerEnum getSerializerType(); 17 18 /** 19 * java对象转换成二进制 20 */ 21 byte[] serialize(Object object); 22 23 /** 24 * 二进制转换成 java 对象 25 */ 26 <T> T deserialize(Class<T> clazz, byte[] bytes); 27 }
2、序列化实现
1 package serializer.impl; 2 3 import com.alibaba.fastjson.JSON; 4 import serializer.service.Serializer; 5 import serializer.service.SerializerEnum; 6 7 /** 8 * Json实现序列化与反序列化 9 * 10 * @author liupengr 11 * @date 2020/2/12 18:26 12 */ 13 public class JsonSerializer implements Serializer { 14 @Override 15 public SerializerEnum getSerializerType() { 16 return SerializerEnum.JSON; 17 } 18 19 @Override 20 public byte[] serialize(Object object) { 21 return JSON.toJSONBytes(object); 22 } 23 24 @Override 25 public <T> T deserialize(Class<T> clazz, byte[] bytes) { 26 return JSON.parseObject(bytes, clazz); 27 } 28 }
1 package serializer.impl; 2 3 import com.esotericsoftware.kryo.Kryo; 4 import com.esotericsoftware.kryo.io.Input; 5 import com.esotericsoftware.kryo.io.Output; 6 import serializer.service.Serializer; 7 import serializer.service.SerializerEnum; 8 9 import java.io.ByteArrayInputStream; 10 import java.io.ByteArrayOutputStream; 11 12 13 /** 14 * kryo序列化与反序列化 15 * @author liupengr 16 * @date 2020/2/12 18:26 17 */ 18 public class kryoSerializer implements Serializer { 19 20 /** 21 * 由于kryo不是线程安全的,针对多线程情况下的使用,要对kryo进行一个简单的封装设计,从而可以多线程安全的使用序列化和反序列化 22 */ 23 static final ThreadLocal<Kryo> kryoThreadLocal = ThreadLocal.withInitial(()->{ 24 Kryo kryo = new Kryo(); 25 kryo.setReferences(true); 26 kryo.setRegistrationRequired(false); 27 return kryo; 28 }); 29 30 public static Kryo getInstance() { 31 return kryoThreadLocal.get(); 32 } 33 34 @Override 35 public SerializerEnum getSerializerType() { 36 return SerializerEnum.KRYO; 37 } 38 39 @Override 40 public byte[] serialize(Object object) { 41 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 42 Output output = new Output(byteArrayOutputStream); 43 getInstance().writeClassAndObject(output,object); 44 output.flush(); 45 return byteArrayOutputStream.toByteArray(); 46 } 47 48 @Override 49 public <T> T deserialize(Class<T> clazz, byte[] bytes) { 50 ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(bytes); 51 Input input=new Input(byteArrayInputStream); 52 return (T) getInstance().readClassAndObject(input); 53 } 54 }
1 package serializer.impl; 2 3 import io.protostuff.LinkedBuffer; 4 import io.protostuff.ProtostuffIOUtil; 5 import io.protostuff.Schema; 6 import io.protostuff.runtime.RuntimeSchema; 7 import serializer.service.Serializer; 8 import serializer.service.SerializerEnum; 9 10 /** 11 * protoStuff 序列化与反序列化 12 * @author liupengr 13 * @date 2020/2/12 18:28 14 */ 15 public class ProtoStuffSerializer implements Serializer{ 16 @Override 17 public SerializerEnum getSerializerType() { 18 return SerializerEnum.PROTOSTUFF; 19 } 20 21 @Override 22 public byte[] serialize(Object object) { 23 //RuntimeSchema类用于在运行时从Java实体对象中生成所需的模式Schema 24 Schema<Object> scheme = (Schema<Object>) RuntimeSchema.createFrom(object.getClass()); 25 //LinkedBuffer是一个缓冲区类,它封装了字节数组并具有对下一个缓冲区的引用以便能动态增加容量。 26 LinkedBuffer linkedBuffer=LinkedBuffer.allocate(512); 27 //ProtostuffIOUtil是一个工具类,用于对消息或对象进行序列化/反序列化 28 return ProtostuffIOUtil.toByteArray(object,scheme,linkedBuffer); 29 } 30 31 @Override 32 public <T> T deserialize(Class<T> clazz, byte[] bytes) { 33 Schema<T> schema = RuntimeSchema.getSchema(clazz); 34 T t = schema.newMessage(); 35 ProtostuffIOUtil.mergeFrom(bytes, t, schema); 36 return t; 37 } 38 }
3、序列化工厂
1 package serializer.impl; 2 3 import serializer.service.Serializer; 4 import serializer.service.SerializerEnum; 5 6 /** 7 * @author liupengr 8 * @date 2020/2/12 16:08 9 */ 10 public class SerializerFactory { 11 12 public static Serializer getSerializerInstance(SerializerEnum serializerEnum) { 13 switch (serializerEnum.getCode()) { 14 case 1: 15 return new JsonSerializer(); 16 case 2: 17 return new kryoSerializer(); 18 case 3: 19 return new ProtoStuffSerializer(); 20 default: 21 return new ProtoStuffSerializer(); 22 } 23 } 24 }
4、序列化枚举
1 package serializer.service; 2 3 /** 4 * @author liupengr 5 * @date 2020/2/12 18:30 6 */ 7 public enum SerializerEnum { 8 JSON(1, "Json"), 9 KRYO(2, "Kryo"), 10 PROTOSTUFF(3, "ProtoStuff"); 11 private Integer code; 12 private String description; 13 14 private SerializerEnum(Integer code, String desc) { 15 this.code = code; 16 this.description = desc; 17 } 18 19 public Integer getCode() { 20 return code; 21 } 22 23 public String getDescription() { 24 return description; 25 } 26 27 public static SerializerEnum valueOf(int code) { 28 for (SerializerEnum source : values()) { 29 if (source.code == code) { 30 return source; 31 } 32 } 33 return null; 34 } 35 }
Don’t hurry say have no choice, perhaps, next intersection will meet hope.