基於protostuff的序列化工具類開發
[toc]
基於protostuff的序列化工具類開發
前言
前面在介紹protostuff的基本使用時(可以參考文章protostuff基本使用),都是針對某個類寫的序列化和反序列化方法,顯然這樣不具有通用性,例如在進行遠端過程呼叫時,傳輸的物件並不唯一,這時就需要開發具有通用性的序列化工具類,即不管序列化的物件是什麼型別,都可以使用該工具類進行序列化。下面就來開發這樣的工具類。
基於這個需要,下面會開發兩個序列化工具類,一個是不具有快取功能的SerializationUtil
,一個是具有快取功能的增強版本SerializationUtil2
。
需要注意的是,protostuff序列化工具類的開發需要大量使用到Java泛型的知識,因此在閱讀這些原始碼時應該需要具有一定的泛型知識儲備,否則程式碼閱讀起來會比較難懂,儘管我已經全部加了註釋。
protostuff序列化工具類SerializationUtil
下面直接給出原始碼:
package cn.xpleaf.protostuff.netty.utils;import com.dyuproject.protostuff.LinkedBuffer;import com.dyuproject.protostuff.ProtostuffIOUtil;import com.dyuproject.protostuff.runtime.RuntimeSchema;/** * 序列化工具類,基於Protostuff實現(其基於Google Protobuf實現) * * @author yeyonghao * */public class SerializationUtil { /** * 序列化方法,將物件序列化為位元組陣列(物件 ---> 位元組陣列) * * @param obj * @return */ @SuppressWarnings("unchecked") public staticbyte[] serialize(T obj) { // 獲取泛型物件的型別 Class clazz = (Class ) obj.getClass(); // 建立泛型物件的schema物件 RuntimeSchema schema = RuntimeSchema.createFrom(clazz); // 建立LinkedBuffer物件 LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); // 序列化 byte[] array = ProtostuffIOUtil.toByteArray(obj, schema, buffer); // 返回序列化物件 return array; } /** * 反序列化方法,將位元組陣列反序列化為物件(位元組陣列 ---> 物件) * * @param data * @param clazz * @return */ public static T deserialize(byte[] data, Class clazz) { // 建立泛型物件的schema物件 RuntimeSchema schema = RuntimeSchema.createFrom(clazz); // 根據schema例項化物件 T message = schema.newMessage(); // 將位元組陣列中的資料反序列化到message物件 ProtostuffIOUtil.mergeFrom(data, message, schema); // 返回反序列化物件 return message; }}
protostuff序列化工具類SerializationUtil2
SerializationUtil的問題在於,每次呼叫序列化方法和反序列化方法時都需要重新生成一個schema物件,所以可以把生成的schema物件儲存起來,在下一次呼叫方法時就不需要重新生成這些schema物件,這樣可以提高序列化和反序列化的效能。
package cn.xpleaf.protostuff.netty.utils;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import com.dyuproject.protostuff.LinkedBuffer;import com.dyuproject.protostuff.ProtostuffIOUtil;import com.dyuproject.protostuff.runtime.RuntimeSchema;/** * 具備快取功能的序列化工具類,基於Protostuff實現(其基於Google Protobuf實現) * * @author yeyonghao * */public class SerializationUtil2 { // 快取schema物件的map private static Map, RuntimeSchema>> cachedSchema = new ConcurrentHashMap , RuntimeSchema>>(); /** * 根據獲取相應型別的schema方法 * * @param clazz * @return */ @SuppressWarnings({ "unchecked", "unused" }) private RuntimeSchema getSchema(Class clazz) { // 先嚐試從快取schema map中獲取相應型別的schema RuntimeSchema schema = (RuntimeSchema ) cachedSchema.get(clazz); // 如果沒有獲取到對應的schema,則建立一個該型別的schema // 同時將其新增到schema map中 if (schema == null) { schema = RuntimeSchema.createFrom(clazz); if (schema != null) { cachedSchema.put(clazz, schema); } } // 返回schema物件 return schema; } /** * 序列化方法,將物件序列化為位元組陣列(物件 ---> 位元組陣列) * * @param obj * @return */ @SuppressWarnings("unchecked") public static byte[] serialize(T obj) { // 獲取泛型物件的型別 Class clazz = (Class ) obj.getClass(); // 建立泛型物件的schema物件 RuntimeSchema schema = RuntimeSchema.createFrom(clazz); // 建立LinkedBuffer物件 LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); // 序列化 byte[] array = ProtostuffIOUtil.toByteArray(obj, schema, buffer); // 返回序列化物件 return array; } /** * 反序列化方法,將位元組陣列反序列化為物件(位元組陣列 ---> 物件) * * @param data * @param clazz * @return */ public static T deserialize(byte[] data, Class clazz) { // 建立泛型物件的schema物件 RuntimeSchema schema = RuntimeSchema.createFrom(clazz); // 根據schema例項化物件 T message = schema.newMessage(); // 將位元組陣列中的資料反序列化到message物件 ProtostuffIOUtil.mergeFrom(data, message, schema); // 返回反序列化物件 return message; }}
測試
測試程式碼如下:
package cn.xpleaf.protostuff.netty.utils;import static org.junit.Assert.*;import org.junit.Test;import cn.xpleaf.pojo.User;public class TestUtil { @Test public void testUtil01() throws Exception { User user = new User("xpleaf", 10); System.out.println(user); // 序列化 byte[] array = SerializationUtil.serialize(user); // 反序列化 User user2 = SerializationUtil.deserialize(array, User.class); System.out.println(user2); // 判斷值是否相等 System.out.println(user.toString().equals(user2.toString())); } @Test public void testUtil02() throws Exception { User user = new User("xpleaf", 10); System.out.println(user); // 序列化 byte[] array = SerializationUtil2.serialize(user); // 反序列化 User user2 = SerializationUtil2.deserialize(array, User.class); System.out.println(user2); // 判斷值是否相等 System.out.println(user.toString().equals(user2.toString())); }}
執行testUtil01時的輸出結果如下:
User [name=xpleaf, age=10]User [name=xpleaf, age=10]true
執行testUtil02時的輸出結果如下:
User [name=xpleaf, age=10]User [name=xpleaf, age=10]true
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2471/viewspace-2813881/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- jackson、fastjson、kryo、protostuff等序列化工具效能對比ASTJSON
- Protocol Buffer序列化Java框架-ProtostuffProtocolJava框架
- 基於微信開發的一款工具類小程式。
- 基於Docker封裝的開發包工具Docker封裝
- 基於 Angular 開發的 紀念日計算工具Angular
- 基於slf4j的日誌工具類
- 基於jquery+html開發的json格式校驗工具jQueryHTMLJSON
- CatiaMagic — 基於MBSE的產品創新和正向開發工具
- 基於Koa.js的微信工具類小記JS
- 基於node.js的腳手架工具開發經歷Node.js
- Java開發常用的16個工具類Java
- 基於TP3.2和Bootstrap開發的歌詞類網站boot網站
- Json反序列化物件通用工具類JSON物件
- Android開發工具類之DownloadManagerProAndroid
- 基於eTS高效開發HarmonyOS課程類應用ASGR
- 基於 Hyperf 開發的商城
- 基於Github的敏捷開發Github敏捷
- 基於TODO的開發方法
- 2.1 基於python開發的資料比對工具--SYDCTOOL介紹Python
- 一款基於 Java 開發的微信資料分析工具!Java
- java實現Excel定製匯出(基於POI的工具類)JavaExcel
- 基於 VSCode下的 Flutter 開發VSCodeFlutter
- 基於WDF的驅動開發
- 碎閱:一款基於douban及ONE API開發的資訊類AppAPIAPP
- Laravel 開發者工具類 - Laravel-debugbar。Laravel
- 基於Ruby的Burpsuite外掛開發UI
- 基於gin的golang web開發:路由GolangWeb路由
- 基於ThinkPHP開發的公司官網PHP
- 基於Docker的LNMP開發環境DockerLNMP開發環境
- 基於ThinkPHP開發的好處如下:PHP
- 基於gin的golang web開發:dockerGolangWebDocker
- Realm:一個基於 Rust 的全新流量轉發工具Rust
- 自己開發的線上視訊下載工具,基於Java多執行緒Java執行緒
- akka-grpc - 基於akka-http和akka-streams的scala gRPC開發工具RPCHTTP
- 併發工具類
- 常用的幾個提高iOS開發效率的開源類庫及工具iOS
- # BaseController 基礎Controller 工具類Controller
- 安裝用於 Windows 應用開發的工具Windows