基于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 }
View Code

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 }
JSON
 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 }
kryo
 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 }
protostuff

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 }
factory

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 }
enum

 

posted @ 2020-02-12 19:18  以梦为码  阅读(512)  评论(0编辑  收藏  举报