免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
《從零開始搭建游戲服務(wù)器》 序列化工具(最優(yōu)版Protostuff)

前言:

之前使用protobuf工具來解析表格數(shù)據(jù)和定制網(wǎng)絡(luò)協(xié)議,但是為了網(wǎng)絡(luò)安全和壓縮數(shù)據(jù)大小,有時候需要對數(shù)據(jù)進行序列化,這就需要設(shè)計一個序列化工具類來完成序列化和反序列化的操作。

框架的對比:

Java中幾個常用的序列化框架對比,包括:kryoHessian、ProtostuffProtostuff-Runtimejava.io

框架 優(yōu)點 缺點
kryo 速度快,序列化后體積小 跨語言支持比較復(fù)雜
Hessian 默認支持跨語言 速度比較慢
java.io JDK自帶功能,使用方便,可序列化所有類 速度慢,占空間大
Protostuff 速度快,基于protobuf 需要靜態(tài)編譯
Protostuff-Runtime 無需靜態(tài)編譯,但序列化之前需要預(yù)先傳入Schema 不支持無默認構(gòu)造函數(shù)的類,反序列化時需要用戶自己初始化序列化后的對象,而此工具只負責(zé)對初始化后的對象進行賦值

1.詳細分析:

  • protobuf 的一個缺點是需要數(shù)據(jù)結(jié)構(gòu)的預(yù)編譯過程,首先要編寫 .proto 格式的配置文件,再通過 protobuf 提供的工具生成各種語言響應(yīng)的代碼。由于java具有反射和動態(tài)代碼生成的能力,這個預(yù)編譯過程不是必須的,可以在代碼執(zhí)行時來實現(xiàn)。有個 protostuff插件 已經(jīng)實現(xiàn)了這個功能。

  • protostuff 基于Google protobuf,但是提供了更多的功能和更簡易的用法。其中,protostuff-runtime 實現(xiàn)了無需預(yù)編譯對Java bean進行protobuf序列化/反序列化的能力。protostuff-runtime的局限是序列化前需預(yù)先傳入schema,反序列化不負責(zé)對象的創(chuàng)建只負責(zé)復(fù)制,因而必須提供默認構(gòu)造函數(shù)。此外,protostuff 還可以按照protobuf的配置序列化成json/yaml/xml等格式。

2.坑點解決:

沒經(jīng)過修改過的 protostuff,性能方法還是有些缺陷,這里我在一篇關(guān)于 輕量級分布式 RPC 框架 博客中找到了據(jù)說是當(dāng)前性能最優(yōu)的 優(yōu)化版Protostuff 的使用案例。
在原生的 Protostuff 中通過反射實例化java類的時候,是通過使用 Class.newInstance() 方法來實現(xiàn)的,而前提就是這個類java類必須提供默認構(gòu)造函數(shù)。
假如希望在java類不提供默認構(gòu)造函數(shù)的時候也能實現(xiàn)反射實例化,可以選擇使用 objenesis 來實例化java類,使用方式可以參考 objenesis官網(wǎng)

3.框架選擇:

綜合上述的分析,最終我還是選擇了 Protostuff 框架來完成Protobuf數(shù)據(jù)的序列化,關(guān)于不支持無默認構(gòu)造函數(shù)類序列化的缺陷接下來通過使用 objenesis 也會得到解決。

自定義序列化工具類

這里我們創(chuàng)建此工具類,取名為 SerializationUtil,使用Protostuff來序列化和反序列化Protobuf數(shù)據(jù):

1.庫引入:

首先要在pom.xml里添加com.dyuproject.protostuffobjenesis的jar包:

 <dependency>       <groupId>com.dyuproject.protostuff</groupId>       <artifactId>protostuff-core</artifactId>       <version>1.0.8</version>   </dependency>   <dependency>       <groupId>com.dyuproject.protostuff</groupId>       <artifactId>protostuff-runtime</artifactId>       <version>1.0.8</version>   </dependency>   <!-- Objenesis --> <dependency>     <groupId>org.objenesis</groupId>     <artifactId>objenesis</artifactId>     <version>2.1</version> </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2.工具類編寫:

主要包含兩個核心的函數(shù):序列化函數(shù) Serializer 和反序列化函數(shù) Deserializer

import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import org.objenesis.Objenesis;import org.objenesis.ObjenesisStd;import com.dyuproject.protostuff.LinkedBuffer;import com.dyuproject.protostuff.ProtostuffIOUtil;import com.dyuproject.protostuff.Schema;import com.dyuproject.protostuff.runtime.RuntimeSchema;public class SerializationUtil {    private static Map<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<>();    private static Objenesis objenesis = new ObjenesisStd(true);    private SerializationUtil() {    }    @SuppressWarnings("unchecked")    private static <T> Schema<T> getSchema(Class<T> cls) {        Schema<T> schema = (Schema<T>) cachedSchema.get(cls);        if (schema == null) {            schema = RuntimeSchema.createFrom(cls);            if (schema != null) {                cachedSchema.put(cls, schema);            }        }        return schema;    }    @SuppressWarnings("unchecked")    public static <T> byte[] serialize(T obj) {        Class<T> cls = (Class<T>) obj.getClass();        LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);        try {            Schema<T> schema = getSchema(cls);            return ProtostuffIOUtil.toByteArray(obj, schema, buffer);        } catch (Exception e) {            throw new IllegalStateException(e.getMessage(), e);        } finally {            buffer.clear();        }    }    public static <T> T deserialize(byte[] data, Class<T> cls) {        try {            T message = (T) objenesis.newInstance(cls);            Schema<T> schema = getSchema(cls);            ProtostuffIOUtil.mergeFrom(data, message, schema);            return message;        } catch (Exception e) {            throw new IllegalStateException(e.getMessage(), e);        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

上面是引入 objenesis 之后的版本,優(yōu)點就是支持沒有提供默認構(gòu)造函數(shù)的java類的實例化,可以看到這里通過 Class<T> cls = (Class<T>) obj.getClass(); 來實例化java類的。ConcurrentHashMap是適用于高并發(fā)的Map數(shù)據(jù)結(jié)構(gòu)。

3.工具類調(diào)用:

隨便定義一個Protobuf的協(xié)議類,假設(shè)為User,下面就是具體的序列化工具使用操作:

  • 序列化:

    byte[] data = SerializationUtil.serialize(user,User.class);  
    • 1
    • 1
  • 反序列化:

    User user2 = SerializationUtil.deserialize(data,User.class); 
    • 1
    • 1

參考資料:

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
【RPC 專欄】深入理解RPC之序列化篇--總結(jié)篇
Unity手游之路<二>Java版服務(wù)端使用protostuff簡化protobuf開發(fā)
RPC, Serialization and Schema
ProtoBuf 常用序列化/反序列化API
RPC框架比較
連接格式優(yōu)化,支持自定義
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服