如何自定义serializer?
只需要实现org.ehcache.spi.serialization.Serializer接口的serialize、read、equals这3个方法即可,来看该接口的说明
这里要强调的是后两点,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 }