JDK自带的序列化效率很低,速度慢且序列化后的字节数组占空间大。通常推荐使用第三方的序列化工具,比如Protostuff库,它是基于Google的Protobuf实现的序列化方法。原生的Protobuffer使用起来相当麻烦,首先要写.proto文件,然后编译.proto文件,生成对应的.java文件。Protostuff在几乎不损耗性能的情况下做到了不需要再写.proto文件来实现序列化。
使用Protostuff库需要引入的Maven依赖:
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>io.protostuff</groupId> <artifactId>protostuff-runtime</artifactId> <version>1.6.0</version> </dependency> <dependency> <groupId>io.protostuff</groupId> <artifactId>protostuff-core</artifactId> <version>1.6.0</version> </dependency>
|
代码示例:
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 58 59
| package com.lzumetal.serialize.protostuff;
import io.protostuff.LinkedBuffer; import io.protostuff.ProtobufIOUtil; import io.protostuff.ProtostuffIOUtil; import io.protostuff.Schema; import io.protostuff.runtime.RuntimeSchema;
import java.util.Map; import java.util.concurrent.ConcurrentHashMap;
public class ProtostuffUtil {
private static Map<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<>();
private static <T> Schema<T> getSchema(Class<T> cls) { Schema<T> schema = (Schema<T>) cachedSchema.get(cls); if (schema == null) { schema = RuntimeSchema.createFrom(cls); cachedSchema.put(cls, schema); } return schema; }
public static <T> byte[] serializer(T obj) { Class<T> clazz = (Class<T>) obj.getClass(); LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); try { Schema<T> schema = RuntimeSchema.getSchema(clazz); return ProtobufIOUtil.toByteArray(obj, schema, buffer); } catch (Exception e) { throw new IllegalStateException(e.getMessage(), e); } finally { buffer.clear(); } }
public static <T> T deserializer(byte[] bytes, Class<T> clazz) {
T obj = null; try { obj = clazz.newInstance(); Schema schema = RuntimeSchema.getSchema(obj.getClass()); ProtostuffIOUtil.mergeFrom(bytes, obj, schema); } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); }
return obj; }
}
|
构建schema的过程可能会比较耗时,因此希望使用过的类对应的schema能被缓存起来。代码如下:
1 2 3 4 5 6 7 8 9 10
| private static Map<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<>();
private static <T> Schema<T> getSchema(Class<T> cls) { Schema<T> schema = (Schema<T>) cachedSchema.get(cls); if (schema == null) { schema = RuntimeSchema.createFrom(cls); cachedSchema.put(cls, schema); } return schema; }
|