升级kryo到5.5.0 KryoFactory工厂类丢失问题
- 引文项目一直使用的是老版本创建对象池,使用对象池的目的是为了线程安全,但是在升级5.5.0之后 Kryo移除了KryoFactory类,所以导致项目中序列化类异常问题描述如下:
未升级前
- 未升级前序列化对象池如下:
// 先试用KryoFactory 工厂创建一个Kryo 对象
KryoFactory factory = new KryoFactory() {
@Override
public Kryo create() {
Kryo kryo = new Kryo();
// 在5.0之后 registrationRequired 默认值为true,需要手动关闭,
kryo.setRegistrationRequired(false);
return kryo;
}
};
// 在使用KryoPool创建一个KryoPool对象池用于后面使用
KryoPool pool = new KryoPool.Builder(factory).softReferences().build();
- 使用对象池
@Override
public byte[] serialize(Object o) {
Kryo kryo = null;
Output outPut = null;
try {
// 从对象池中获取到kryo 对象
kryo = pool.borrow();
outPut = new Output(KRYO_OUTPUT_BUFFER_SIZE, KRYO_OUTPUT_MAX_BUFFER_SIZE);
kryo.writeClassAndObject(outPut, o);
outPut.flush();
return outPut.toBytes();
} finally {
// 使用结束,将kryo对象归还对象池
pool.release(kryo);
if (outPut != null) {
outPut.close();
}
}
}
升级版本
问题
- pom修改
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<version>5.5.0</version>
</dependency>
- 升级后如下图
KryoFactory 以及 KryoPool 找不到了,原因是 在Kryo 5.5.0版本中,类com.esotericsoftware.kryo.pool.KryoFactory被移动到了新的包路径下。具体来说,该类从原来的com.esotericsoftware.kryo.pool包下移动到了com.esotericsoftware.kryo.util包下。
解决方案
-
因为新版本移动了相关类的路径,并且去掉了KryoFactory类,所一不能再用以前的方式创建对象池了,最新的创建方式如下:
-
创建对象池
/**
* 1. 参数详解:池构造函数参数:线程安全、软引用、最大容量 :
* public Pool(boolean threadSafe, boolean softReferences, final int maximumCapacity)
* threadSafe: 这个参数是制定是否需要再POOL内部同步,如果设置为true,则可以被多个线程并发访问。
* softReferences: 这个参数是是否使用softReferences进行存储对象,如果设置为true,则Kryo 池将会使用 java.lang.ref.SoftReference 来存储对象。这允许池中的对象在 JVM 的内存压力大时被垃圾回收。
*/
Pool<Kryo> kryoPool = new Pool<Kryo>(true, false, 8) {
protected Kryo create() {
Kryo kryo = new Kryo();
// Kryo 配置
return kryo;
}
};
- 对象池使用:
@Override
public byte[] serialize(Object o) {
Kryo kryo = null;
Output outPut = null;
try {
// 5.5.0已经移除了pool.borrow();方法替换使用obtain()
kryo = kryoPool.obtain();
outPut = new Output(KRYO_OUTPUT_BUFFER_SIZE, KRYO_OUTPUT_MAX_BUFFER_SIZE);
kryo.writeClassAndObject(outPut, o);
outPut.flush();
return outPut.toBytes();
} finally {
// 5.5.0已经移除了pool.release();方法替换使用free()
kryoPool.free(kryo);
if (outPut != null) {
outPut.close();
}
}
}