目標:介紹dubbo中序列化的內容,對dubbo中支持的序列化方式作對比,介紹dubbo-serialization-api下的源碼
序列化就是將對象轉成字節流,用於網絡傳輸,以及將字節流轉爲對象,用於在收到字節流數據後還原成對象。序列化的好處我就很少說了,無非就是安全性更好、可跨平臺等。網上有不少總結的很好,我在這裏主要講講dubbo中序列化的設計和實現了哪些序列化方式。java
dubbo在2.6.x版本中,支持五種序列化方式,分別是git
在dubbo最新的2.7.0版本中支持了protostuff,以前的版本dubbo還實現了本身的dubbo序列化,可是因爲還不夠成熟,全部暫時移除了dubbo序列化的實現。github
從性能上對比,fst和kryo>hessian2>fastjson>jdk。json
他們具體的實現我不講解,由於不少都直接使用了對應的依賴褲,我只講解dubbo序列化的接口設計。api
public interface DataInput { /** * Read boolean. * 讀取布爾類型 * @return boolean. * @throws IOException */ boolean readBool() throws IOException; /** * Read byte. * 讀取字節 * @return byte value. * @throws IOException */ byte readByte() throws IOException; /** * Read short integer. * 讀取short類型 * @return short. * @throws IOException */ short readShort() throws IOException; /** * Read integer. * 讀取integer類型 * @return integer. * @throws IOException */ int readInt() throws IOException; /** * Read long. * 讀取long類型 * @return long. * @throws IOException */ long readLong() throws IOException; /** * Read float. * 讀取float類型 * @return float. * @throws IOException */ float readFloat() throws IOException; /** * Read double. * 讀取double類型 * @return double. * @throws IOException */ double readDouble() throws IOException; /** * Read UTF-8 string. * 讀取UTF-8 string * @return string. * @throws IOException */ String readUTF() throws IOException; /** * Read byte array. * 讀取byte數組 * @return byte array. * @throws IOException */ byte[] readBytes() throws IOException; }
該接口是數據輸入接口,能夠看到定義了從 InputStream 中各種數據類型的讀取方法。數組
public interface DataOutput { /** * Write boolean. * 輸出boolean類型 * @param v value. * @throws IOException */ void writeBool(boolean v) throws IOException; /** * Write byte. * 輸出byte類型 * @param v value. * @throws IOException */ void writeByte(byte v) throws IOException; /** * Write short. * 輸出short類型 * @param v value. * @throws IOException */ void writeShort(short v) throws IOException; /** * Write integer. * 輸出integer類型 * @param v value. * @throws IOException */ void writeInt(int v) throws IOException; /** * Write long. * 輸出long類型 * @param v value. * @throws IOException */ void writeLong(long v) throws IOException; /** * Write float. * 輸出float類型 * @param v value. * @throws IOException */ void writeFloat(float v) throws IOException; /** * Write double. * 輸出double類型 * @param v value. * @throws IOException */ void writeDouble(double v) throws IOException; /** * Write string. * 輸出string類型 * @param v value. * @throws IOException */ void writeUTF(String v) throws IOException; /** * Write byte array. * 輸出byte數組 * @param v value. * @throws IOException */ void writeBytes(byte[] v) throws IOException; /** * Write byte array. * 輸出byte數組中部分數據 * @param v value. * @param off offset. * @param len length. * @throws IOException */ void writeBytes(byte[] v, int off, int len) throws IOException; /** * Flush buffer. * 刷新緩衝區 * @throws IOException */ void flushBuffer() throws IOException; }
該接口是數據輸出接口,能夠看到定義了向 InputStream 中,寫入基本類型的數據。安全
public interface ObjectOutput extends DataOutput { /** * write object. * 輸入object類型 * @param obj object. */ void writeObject(Object obj) throws IOException; }
在 DataOutput 的基礎上,增長寫入object類型的數據。網絡
public interface ObjectInput extends DataInput { /** * read object. * 讀取object類型數據 * @return object. */ Object readObject() throws IOException, ClassNotFoundException; /** * read object. * 根據class類型讀取object類型數據 * @param cls object type. * @return object. */ <T> T readObject(Class<T> cls) throws IOException, ClassNotFoundException; /** * read object. * 取object類型數據 * @param cls object type. * @return object. */ <T> T readObject(Class<T> cls, Type type) throws IOException, ClassNotFoundException; }
該接口是繼承了DataInput 接口,在 DataInput 的基礎上,增長讀取object類型的數據。框架
public interface Cleanable { /** * 清理 */ void cleanup(); }
該接口是清理接口,定義了一個清理方法。目前只有kryo實現的時候,完成序列化或反序列化,須要作清理。經過實現該接口,執行清理的邏輯。工具
@SPI("hessian2") public interface Serialization { /** * get content type id * 得到內容類型編號 * @return content type id */ byte getContentTypeId(); /** * get content type * 得到內容類型名 * @return content type */ String getContentType(); /** * create serializer * 建立 ObjectOutput 對象,序列化輸出到 OutputStream * @param url * @param output * @return serializer * @throws IOException */ @Adaptive ObjectOutput serialize(URL url, OutputStream output) throws IOException; /** * create deserializer * 建立 ObjectInput 對象,從 InputStream 反序列化 * @param url * @param input * @return deserializer * @throws IOException */ @Adaptive ObjectInput deserialize(URL url, InputStream input) throws IOException; }
該接口是序列化接口,該接口也是可擴展接口,默認是使用hessian2序列化方式。其中定義了序列化和反序列化等方法
public abstract class SerializableClassRegistry { /** * 可序列化類類的集合 */ private static final Set<Class> registrations = new LinkedHashSet<Class>(); /** * only supposed to be called at startup time * 把可序列化的類加入到集合 */ public static void registerClass(Class clazz) { registrations.add(clazz); } /** * 得到可序列化的類的集合 * @return */ public static Set<Class> getRegisteredClasses() { return registrations; } }
該類提供一個序列化統一的註冊中心,其實就是封裝了可序列化類的集合
public interface SerializationOptimizer { /** * 須要序列化的類的集合 * @return */ Collection<Class> getSerializableClasses(); }
該接口序列化優化器接口,在 Kryo 、FST 中,支持配置須要優化的類。業務系統中,能夠實現自定義的 SerializationOptimizer,進行配置。或者使用文件來配置也是一個選擇。
該部分相關的源碼解析地址: https://github.com/CrazyHZM/i...
該文章講解了dubbo支持的幾種序列化方式,介紹了序列化的接口設計,具體的實現我再也不講述,由於大部分都是調用了不一樣的依賴庫。接下來我會說一個分割線,我講開始講解2.7.x版本的新特性,而後分析新特性的實現,下一篇就先講解一下dubbo2.7.0的大改動。