关于如何使用Kryo完成序列化和反序列化
基于kryo完成序列化和反序列化1. Kryo的使用
Step01:定义mail类:package com.java.serializable; import java.io.Serializable; import java.util.Date; public class Mail implements Serializable{ private static final long serialVersionUID = 6599166688654530165L; private Integer id; private String title; private String content; private Date createdTime; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Date getCreatedTime() { return createdTime; } public void setCreatedTime(Date createdTime) { this.createdTime = createdTime; } @Override public String toString() { return "Mail [id=" + id + ", title=" + title + ", content=" + content + ", createdTime=" + createdTime + "]"; } }
Step02:添加依赖 com.esotericsoftware kryo 5.0.0-RC4
Step03:编写测试类package com.java.serializable; import java.util.Date; import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream; import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; public class TestSerializable06 { public static void main(String[] args) { Mail m=new Mail(); m.setId(100); m.setTitle("test"); m.setContent("this is test content"); m.setCreatedTime(new Date()); //基于Kryo框架将对象序列化 Kryo kryo=new Kryo(); //将默认类的自动注册功能关闭(默认会将类全名序列化) kryo.setRegistrationRequired(false); //kryo.register(Mail.class); //kryo.register(Date.class); ByteArrayOutputStream bos=//内置可扩容数组 new ByteArrayOutputStream(); Output output=new Output(bos); kryo.writeObject(output, m); //写入null时会报错 output.close(); System.out.println("序列化ok"); //基于Kryo框架将对象反序列化 byte[] data=bos.toByteArray(); Input input=new Input(data); Mail m2=kryo.readObject(input,Mail.class); //读出null时会报错 input.close(); System.out.println(m2); } }
结果:序列化ok Mail [id=100, title=test, content=this is test content, createdTime=Mon Nov 11 14:15:35 CST 2019]2. 工具类
可将如上序列化方法进行封装,写到序列化工具类中,例如:public class KryoSerializer { private static final ThreadLocal kryoLocal = ThreadLocal.withInitial(() -> { Kryo kryo = new Kryo(); kryo.setReferences(true);//检测循环依赖,默认值为true,避免版本变化显式设置 kryo.setRegistrationRequired(false);//默认值为true,避免版本变化显式设置 ((DefaultInstantiatorStrategy) kryo.getInstantiatorStrategy()) .setFallbackInstantiatorStrategy(new StdInstantiatorStrategy());//设定默认的实例化器 return kryo; }); public byte[] serialize(Object obj) { Kryo kryo = getKryo(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); Output output = new Output(byteArrayOutputStream); kryo.writeClassAndObject(output, obj); output.close(); return byteArrayOutputStream.toByteArray(); } public T deserialize(byte[] bytes) { Kryo kryo = getKryo(); Input input = new Input(new ByteArrayInputStream(bytes)); return (T) kryo.readClassAndObject(input); } private Kryo getKryo() { return kryoLocal.get(); } }
编写测试类:package com.java.serializable; import java.io.IOException; import java.util.Date; public class TestSerializable07 { public static void main(String[] args)throws IOException { Mail m=new Mail(); m.setId(100); m.setTitle("test"); m.setContent("this is test content"); m.setCreatedTime(new Date()); //基于Kryo框架将对象序列化 byte[] array= KryoSerializer.serializable(m); System.out.println("序列化OK,array.length="+array.length); //基于Kryo框架将对象反序列化 Mail m2= KryoSerializer.deserialization(array,Mail.class); System.out.println(m2); } }
运行结果:序列化OK,array.length=49 Mail [id=100, title=test, content=this is test content, createdTime=Mon Nov 11 18:04:03 CST 2019]3. 两种读写方式
根据是否写入class类型分为两种方式, 这里特别指出这里的的class指的是读写对象的class, 如果读写的是有嵌套类型对象,则不管采用哪种方式, 子类型class都会序列化.3.1 只写实例信息知道class且对象不为nullkryo.writeObject(output, someObject); // ... SomeClass someObject = kryo.readObject(input, SomeClass.class);知道class且对象可能为nullkryo.writeObjectOrNull(output, someObject); // ... SomeClass someObject = kryo.readObjectOrNull(input, SomeClass.class);3.2 同时写入class类型和实例信息(RPC场景)
class未知且对象可能为null, 但这种场景, 会多占用空间. 这种方式是我们在RPC中应当使用的方式kryo.writeClassAndObject(output, object); // ... Object object = kryo.readClassAndObject(input); if (object instanceof SomeClass) { // ... }4. 相关配置
register类注册
kryo支持通过类注册, 注册会给每一个class一个int类型的Id相关联,这显然比类名称高效,但同时要求反序列化的时候的Id必须与序列化过程中一致。这意味着注册的顺序非常重要。kryo.register(SomeClassA.class); kryo.register(SomeClassB.class);
但是由于现实原因,同样的代码,同样的Class在不同的机器上注册编号任然不能保证一致,所以多机器部署时候反序列化可能会出现问题。
所以kryo默认会开启类注册(version:5.0.2),可以通过kryo.setRegistrationRequired(false)关闭, 关闭后Kryo会根据类型去loadClass关联kryo.setRegistrationRequired(false);//一般设置为false解决线程不安全
由于Kryo线程不安全, 意味着每次序列化和反序列化时都需要实例化一次, 或借助ThreadLocal来维护以保证其线程安全。private static final ThreadLocal kryos = new ThreadLocal() { protected Kryo initialValue() { Kryo kryo = new Kryo(); // configure kryo instance, customize settings return kryo; }; }; // Somewhere else, use Kryo Kryo k = kryos.get(); ...
或者使用kryo提供的pool:public KryoPool newKryoPool() { return new KryoPool.Builder(() -> { final Kryo kryo = new Kryo(); kryo.setInstantiatorStrategy(new Kryo.DefaultInstantiatorStrategy( new StdInstantiatorStrategy())); return kryo; }).softReferences().build(); }
千元平板内卷之王台电T40Pro如今千元价位的平板电脑款式越来越多,也越来越内卷,但要说哪款平板才是千元平板的内卷之王,台电T40Pro就有这个实力。作为台电的T系列平板电脑,T40Pro的各项配置都非常不错,屏
海松资本创始人陈立光硬核科技投资正当时9月27日,弗若斯特沙利文与钛媒体联合主办的2022首届新投资博览会在上海国际会议中心举行,会议上海松资本创始人CEO兼管理合伙人陈立光发表了硬核科技投资正当时主题演讲,表示中国投
甘肃人到底多能吃羊?烤羊排。摄影跨界大叔,图图虫创意风物君语不去甘肃吃只羊,这个秋天就白过了秋风吹破玉门关,整个甘肃就飘起羊肉的香味。长期以来,甘肃面的名头盖过羊肉,以至于甘肃人善吃羊的事实经常被外地
东营人这些景点恢复开放黄河口生态旅游区10月7日恢复开放亲爱的游客朋友们根据我市疫情防控政策及景区实际情况,黄河口生态旅游区在严格落实常态化疫情防控各项措施基础上于2022年10月7日起恢复开放。十月的
男子爬山爬一半发现景点在对面山头内心绝望,想飞过去导语爬山是一项有益身心的户外运动,国庆节可能很多人都会选择爬山,在西安,李先生和朋友也选择了去爬翠华山,但却没想到爬到半山腰才发现,想去的景点在对面山头,李先生表示很绝望。网友纷纷
烟台女子沙滩捡30斤虾去晚了海肠已经没有了真是大风过后必有货近日,大风过后,山东烟台多处海滩出现大量海鲜,引不少市民前来赶海。10月7日,当地市民向极目新闻记者介绍,海边泸沽虾成堆,有人直接开来三轮车进货。海滩退潮后现大量海鲜(视频截图)连
怎样把丽江的风月带回家这是我第四次来丽江,前往一些曾经拍过照片的场景,又添了新的照片。仿佛没有一点变化,记忆里的丽江浪漫热烈古朴,置身尘外。丽江比大理多情,比西双版纳内敛。多年前,木府风诡云谲多年后,旅
遇见最美的风景这里是恭城,月柿正当红秋去冬来万物休,唯有柿树挂灯笼。秋天的最后一个节气霜降已经到来,在广西桂林恭城,地标农产品恭城月柿成熟了,莲花镇兰洞村黄竹岗屯的村民沉浸在柿子丰收的喜悦中。在20世纪六七十年代,兰
秦始皇兵马俑博物馆世界八大奇迹之一秦始皇兵马俑博物馆秦始皇兵马俑博物馆位于陕西省西安市临潼区城东。是以秦始皇兵马俑为基础,在兵马俑坑原址上建立的遗址类博物馆。秦始皇兵马俑博物馆共有一二三号3个兵马俑坑。一号坑是一个
2022下半年换机首选这几款,性能优秀价格不贵,轻松能用三五年每年度的下半年都是换手机的好时候,毕竟有双十一双十二这样的优惠大促销,能省下不少钱。今天我们推荐三款适合下半年购买的手机,性能价格都让人挑不出毛病。一vivoS15Pro售价309
自动驾驶博士下田,20万亩地跑起无人拖拉机记者方文宇编辑江昱玢自动驾驶技术,在田间地头发光发热。全栈式农业机器人产品服务提供商中科原动力,以人工智能和自动驾驶技术赋能拖拉机,使其具备全昼夜无人化精准作业能力。据中科原动力创