這是《手寫RPC框架冰悠,我學(xué)會了什么堡妒?》系列的第05篇
上一篇 提到了protobuf。其實參考 官網(wǎng) 很快上手做了一個demo溉卓,但是跟之前寫的RPC框架集成的不是很好(主要卡在Client的部分)皮迟。在搜索資料的過程中看到了一個第三方庫:protostuff。
對比
就 易用性 方面先做一個簡單的對比:
原生的protobuf的诵,需要手寫.proto文件(也就是定義協(xié)議)万栅,再通過編譯生成相應(yīng)的Java代碼,再通過相應(yīng)的API完成序列化和反序列化西疤。
編譯生成的Java代碼有上千行烦粒,而且對于框架有一點的“入侵性”。
protostuff對于POJO支持的很好代赁。
(關(guān)于實現(xiàn)原理這里先再埋個坑扰她,猜測是定義了一個通用的協(xié)議)
實現(xiàn)
基于protostuff實現(xiàn)一個序列化和反序列化的工具,代替之前Java原生的序列化芭碍。
(其實只是對ProtostuffIOUtil做一個簡單的封裝)
/**
* 序列化和反序列化工具類
*
* @author nathan
* @date 2019/3/17
*/
public class SerializingUtil {
/**
* 將目標(biāo)類序列化為byte數(shù)組
*
* @param source
* @param <T>
* @return
*/
public static <T> byte[] serialize(T source) {
RuntimeSchema<T> schema;
LinkedBuffer buffer = null;
byte[] result;
try {
schema = RuntimeSchema.createFrom((Class<T>) source.getClass());
buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
result = ProtostuffIOUtil.toByteArray(source, schema, buffer);
} catch (Exception e) {
throw new RuntimeException("serialize exception");
} finally {
if (buffer != null) {
buffer.clear();
}
}
return result;
}
/**
* 將byte數(shù)組反序列化為目標(biāo)類
*
* @param source
* @param typeClass
* @param <T>
* @return
*/
public static <T> T deserialize(byte[] source, Class<T> typeClass) {
RuntimeSchema<T> schema;
T newInstance;
try {
schema = RuntimeSchema.createFrom(typeClass);
newInstance = typeClass.newInstance();
ProtostuffIOUtil.mergeFrom(source, newInstance, schema);
} catch (Exception e) {
throw new RuntimeException("deserialize exception");
}
return newInstance;
}
}
測試
再用testng寫個測試用例驗證下徒役。
/**
* 序列化和反序列化工具測試類
*
* @author nathan
* @date 2019/3/17
*/
public class SerializingUtilTest {
@Test
public void test() {
String expect = "hello, world.";
byte[] serialized = SerializingUtil.serialize(expect);
Assert.assertEquals(SerializingUtil.deserialize(serialized, String.class), expect);
}
}
Maven依賴
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<version>1.0.7</version>
</dependency>
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<version>1.0.7</version>
</dependency>