kryo浅析
简介
Kryo is a fast and efficient object graph serialization framework for Java. The goals of the project are speed, efficiency, and an easy to use API. The project is useful any time objects need to be persisted, whether to a file, database, or over the network.
– https://github.com/EsotericSoftware/kryo
总结点
- 其使用了字节码生成机制(底层依赖了 ASM 库)
- 必须包含无参构造器
- 不需要实现Serializable接口
- Kryo是线程不安全的,意味着每当需要序列化和反序列化时都需要实例化一次,或者借助ThreadLocal来维护以保证其线程安全。
- 使用 transient 关键字标记的字段不参与序列化
简单实践
maven依赖
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<!--<artifactId>kryo-shaded</artifactId>-->
<version>4.0.2</version>
</dependency>
@Data
public class User2 {
private Long id;
private String name;
private Date date;
private transient String str;
}
package morning.cat.study.kryo;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.pool.KryoPool;
import org.junit.Test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.concurrent.ArrayBlockingQueue;
public class KryoSerializableTest {
@Test
public void test() throws IOException {
// 序列化
Kryo kryo = new Kryo();
Output output = new Output(new FileOutputStream("kryo.bin"));
kryo.writeObject(output, getUser());
output.close();
}
@Test
public void test2() throws IOException {
// 反序列化
Kryo kryo = new Kryo();
Input input = new Input(new FileInputStream("kryo.bin"));
User2 user = kryo.readObject(input, User2.class);
System.out.println(user);
}
private User2 getUser() {
User2 user = new User2();
user.setId(System.currentTimeMillis());
user.setName("Kryo_" + System.currentTimeMillis());
user.setDate(Calendar.getInstance().getTime());
user.setStr("transient 关键字标记 不参与序列化");
System.out.println(user);
return user;
}
private static final ThreadLocal<Kryo> kryos =
new ThreadLocal<Kryo>() {
@Override
protected Kryo initialValue() {
Kryo kryo = new Kryo();
return kryo;
}
};
@Test
public void test3() throws FileNotFoundException {
String fileName = "kryo_test3_3.bin";
// ThreadLocal 方式
Kryo kryo = kryos.get();
kryo.setRegistrationRequired(false);//关闭注册行为
kryo.setReferences(true);//支持循环引用
Output output = new Output(new FileOutputStream(fileName));
kryo.writeClassAndObject(output, getUser());
output.close();
Input input = new Input(new FileInputStream(fileName));
Object object = kryo.readClassAndObject(input);
if (object instanceof User2) {
User2 user = (User2) object;
System.out.println(user);
}
}
@Test
public void test4() {
// 池技术
KryoPool kryoPool = new KryoPool.Builder(() -> new Kryo()).queue(new ArrayBlockingQueue<>(20)).build();
Kryo kryo = kryoPool.borrow();
kryoPool.release(kryo);
}
}
附录
参考文档:
http://www.iocoder.cn/RPC/laoxu/rpc-serialize-1/?geekbook