首页 > 代码库 > ehcache3-serializer二

ehcache3-serializer二

如何自定义serializer?

只需要实现org.ehcache.spi.serialization.Serializer接口的serialize、read、equals这3个方法即可,来看该接口的说明

技术分享

1实现必须线程安全,可以使用ThreadLocal;
2实现必须包含一个含有ClassLoader为参数的构造器,若该ClassLoader非null,则在反序列时需要使用该ClassLoader加载需要反序列的对象的类;
3被序列化对象的class必须被保存;被序列化对象的class与反序列化后的对象的class必须相等。

这里要强调的是后两点,ClassLoader的统一保证了class的统一,在此前提下才能够进行实例的比较。之前介绍了serializer的初始化过程,我们通常会将serializer交由ehcache管理,通过反射构造serializer时就会传入指定的ClassLoader,并且serializer、keyType、valueType的class也是由该classLoader加载。在进行序列化时,如果实例对象的class的classLoader与keyType、valueType的classLoader不一致,就会序列化失败(因为找不到对应的serializer)。

如果在构造CacheManager时没有指定classLoader,则使用ehcache的默认classLoader

技术分享

 

通过下面的逻辑可以看到,keyType、valueType、serializer的class都是通过指定的classLoader加载的

技术分享

 

技术分享

 

技术分享

 

这里我们使用kryo作为ehcache的serializer。

什么是kryo?

官方这样定义kryo,Kryo is a fast and efficient object graph serialization framework for Java,简单的说,kryo就是一个高性能的java序列化框架。

 org.ehcache.spi.serialization.Serializer要求实现serialize、read、equals三个方法。在构造kryo的serializer实现时,可以注册需要序列化的对象的class,这样在使用writeClassAndObject时可以节省大量空间。kryo实例时是非线程安全的,所以可以使用ThreadLocal包装kryo。注意,kryo在反序列时,如果之前未注册,则会使用加载kryo类的classLoader加载类,如果在ehcache中未指定classLoader,这个classLoader也就是ehcache的默认classLoader。

 1     @Override
 2     public ByteBuffer serialize(Object object) throws SerializerException {
 3         byte[] bytes = threadKryo.get().writeClassAndObject(object);
 4         ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
 5         return byteBuffer;
 6     }
 7 
 8     @Override
 9     public Object read(ByteBuffer binary) throws ClassNotFoundException, SerializerException {
10         Object read = null;
11         read = threadKryo.get().readClassAndObject(binary.array());
12         return read;
13     }
14 
15     @Override
16     public boolean equals(Object object, ByteBuffer binary) throws ClassNotFoundException, SerializerException {
17         ByteBuffer serialize = serialize(object);
18         return serialize.equals(binary);
19     }

 

ehcache3-serializer二