Redkale-ConvertJava的序列化與反序列化工具
Convert 是一個(gè)比較獨(dú)立的組件,僅依賴于util包。提供Java對象的序列化與反序列化功能。支持JSON(JavaScript Object Notation)、BSON(Binary Stream Object Notation)兩種格式化。 兩種格式使用方式完全一樣,其性能都大幅度超過其他JSON框架。同時(shí)JSON內(nèi)置于HTTP服務(wù)中,BSON也是SNCP協(xié)議數(shù)據(jù)序列化的基礎(chǔ)。
Convert 快速上手
本介紹僅以JSON為例(BSON與JSON使用方式雷同)。其操作類主要是JsonConvert,配置類主要是JsonFactory、ConvertColumn。JsonFactory采用同ClassLoader類似的雙親委托方式設(shè)計(jì)。
JsonConvert 序列化encode方法:
public String convertTo(final Object value); public String convertTo(final Type type, final Object value); public void convertTo(final OutputStream out, final Object value); public void convertTo(final OutputStream out, final Type type, final Object value); public ByteBuffer[] convertTo(Supplier<ByteBuffer> supplier, final Object value); public ByteBuffer[] convertTo(Supplier<ByteBuffer> supplier, Type type, Object value); public void convertTo(final JsonWriter writer, final Object value); public void convertTo(final JsonWriter writer, final Type type, final Object value);
JsonConvert 反序列化decode方法:
public <T> T convertFrom(final Type type, final String text); public <T> T convertFrom(final Type type, final char[] text); public <T> T convertFrom(final Type type, final char[] text, int start, int len); public <T> T convertFrom(final Type type, final InputStream in); public <T> T convertFrom(final Type type, final ByteBuffer... buffers); public <T> T convertFrom(final Type type, final JsonReader reader);
Convert 與 ByteBuffer 的結(jié)合
從以上的方法可以看出,與其他JSON框架相比Convert多了與ByteBuffer結(jié)合的方法。特別是convertTo方法加了Supplier<ByteBuffer>方法,這么做是為了提高數(shù)據(jù)傳輸?shù)男阅?。在大部分情況下JSON序列化得到的數(shù)據(jù)流是為了傳輸出去,常見的場景就是HTTP+JSON接口。Convert提供ByteBuffer接口會大量減少中間臨時(shí)數(shù)據(jù)的產(chǎn)生。大部分輸出JSON數(shù)據(jù)的方法如下:
public void doPost(HttpRequest req, HttpResponse resp) throws ServletException {
String json = new Gson().toJson(record);
resp.setContentType("text/json; charset=UTF-8");
resp.getOutputStream().write(json.getBytes("UTF-8"));
}
幾乎所有的JSON框架提供的接口以String作為返回結(jié)果為主,其內(nèi)在都是以char[]作為JsonWriter的載體。以Gson為例,Gson拼接JSON默認(rèn)使用的是StringWriter,StringWriter的擴(kuò)容策略是翻倍。為了方便計(jì)算,假設(shè)一個(gè)對象轉(zhuǎn)換成JSON字符串大小為了10K。Gson在轉(zhuǎn)換過程中產(chǎn)生的臨時(shí)的char[]的大小: 16 + 32 + 64 + 128 + 256 + 512 + 1K + 2K + 4K + 8K + 16K = 32K, char[]轉(zhuǎn)換成最終的String結(jié)果又會產(chǎn)生10K的char[], 最后在response輸出時(shí)又會產(chǎn)生10K的byte[](方便計(jì)算不考慮雙字節(jié)),也就是說整個(gè)對象輸出過程中會產(chǎn)生52K的臨時(shí)數(shù)據(jù)。而且常見的HTTP服務(wù)器(如實(shí)現(xiàn)java-servlet規(guī)范的服務(wù)器)不會把底層的ByteBuffer對象池暴露給上層。所以以String為輸出結(jié)果的JSON方法都會產(chǎn)生5倍于數(shù)據(jù)體積大小(其他低于1倍擴(kuò)容策略的框架會產(chǎn)生更多)的垃圾數(shù)據(jù)。
Redkale框架的HTTP服務(wù)內(nèi)置了Convert的JSON接口,避免了大量的垃圾數(shù)據(jù)產(chǎn)生。Redkale的HTTP是基于AIO(NIO.2)實(shí)現(xiàn)且存在ByteBuffer對象池,response的finishJson系列方法將HTTP服務(wù)的ByteBuffer對象池傳給Convert, 使Convert在序列化過程中直接以UTF-8編碼方式輸出到ByteBuffer里,輸出結(jié)束后將ByteBuffer交給對象池回收,從而減少大量構(gòu)建bye[]、char[]所產(chǎn)生的臨時(shí)數(shù)據(jù)。
protected void execute(HttpRequest req, HttpResponse resp) throws IOException {
resp.finishJson(record);
}
詳情見: http://redkale.org/convert.html
