介绍JAVA程序中经常会用到序列化场景。除了JDK本身提供的Serializable,还有一些第三方产品也可以实现JAVA对象。序列化。比较有名的一个是Googleprotobuf。当然还有其他知名的序列化工具,比如Kryo、JBossMarshalling。今天要给大家介绍的是JBossMarshalling。为什么要引入JBossMarshalling?用过googleprotobuf的朋友可能知道,protobuf虽然使用方便,但是在生成对应的protobuf文件之前,还是需要先定义好序列化对象的结构。怕麻烦的朋友可以不考虑。JBossMarshalling是在JDK自带的java.io.Serializable中优化的序列化工具。使用非常简单,兼容java.io.Serializable,是居家开发程序的好帮手。根据JBoss官方介绍,JBossMarshalling与JDKjava.io.Serializable相比有两个非常大的优势。第一个优点是JBossMarshalling解决了java.io.Serializable中使用的一些不便和问题。第二个优势就是JBossMarshalling是完全可插拔的,这就提供了扩展JBossMarshalling框架的可能,下面我们就来看看JBossMarshalling的使用。添加JBossMarshalling依赖项如果您想使用JBossMarshalling,第一步是添加JBossMarshalling依赖项。很奇怪的是,如果你去JBossMarshalling的官网,你可能会发现JBossMarshalling很久没有更新了,它的最新版本是2011-04-27发布的1.3.0.CR9版本。不过不用担心,如果搜索maven仓库,会发现最新的版本是2021年5月发布的2.0.12.Final版本。所以这里我们以最新的2.0.12.Final版本为例进行说明。如果仔细观察JBossMarshalling的maven仓库,可以看到JBossMarshalling包含4个依赖包,分别是JBossMarshallingAPI、JBossMarshallingRiverProtocol、JBossMarshallingSerialProtocol和JBossMarshallingOSGiBundle。JBossMarshallingAPI就是我们需要在程序中调用的API接口,这个必须包含。JBossMarshallingRiverProtocol和JBossMarshallingSerialProtocol是编组的两种实现方式,大家可以根据需要选择。JBoss官网没有太多关于这两种序列化实现的细节。我只能说,据我了解,河流的压缩程度更高。其他细节和实现可能只有阅读源码才能知道。JBossMarshallingOSGiBundle是一个基于OSGi的可插拔框架。如果我们只是序列化对象,那么我们只需要使用JBossMarshallingAPI和JBossMarshallingRiverProtocol。org.jboss.marshallingjboss-marshalling<版本>2.0.12.Finalorg.jboss.marshallingjboss-marshalling-river2.0.12.FinalJBossMarshalling的使用添加依赖后,我们就可以开始使用JBossMarshalling了.JBossMarshalling的使用非常简单。首先,我们需要根据选择的编组方法创建一个MarshallerFactory://使用river作为编组方法MarshallerFactorymarshallerFactory=Marshalling.getProvidedMarshallerFactory("river");这里我们选择使用river作为编组序列化方式。有了MarshallerFactory,我们还需要一个MarshallingConfiguration来为MarshallerFactory提供一些必要的序列化参数。一般来说,我们可以控制MarshallingConfiguration的以下属性:MarshallingConfigurationconfiguration=newMarshallingConfiguration();配置.setVersion(4);配置.setClassCount(10);配置.setBufferSize(8096);配置.setInstanceCount(100);配置.setExceptionListener(newMarshallingException());configuration.setClassResolver(newSimpleClassResolver(getClass().getClassLoader()));setVersion是用于设置的编组协议的版本号,这个版本号很重要,因为依赖的协议实现可能会根据需要升级序列化实现,这可能会造成不兼容。通过设置版本号,可以保证升级后的协议也兼容之前的序列化版本。setClassCount是要序列化的对象中预设的类数。setInstanceCount是预设序列化对象中类实例的个数。setBufferSize设置读取数据的buff大小,可以通过调整该属性来调整序列化性能。setExceptionListener在序列化异常时添加一个异常监听器。setClassResolver用于设置类加载器。JBossMarshalling的强大之处在于,我们还可以在序列化过程中拦截对象,进行日志输出或其他业务操作。配置提供了两个方法,分别是setObjectPreResolver和setObjectResolver。这两个方法接受可用于处理对象的ObjectResolver对象。两种方法的区别在于执行顺序,preResolver在所有解析器之前执行。做好以上配置后,我们就可以正式开始编码了。finalMarshallermarshaller=marshallerFactory.createMarshaller(configuration);try(FileOutputStreamos=newFileOutputStream(fileName)){marshaller.start(Marshalling.createByteOutput(os));marshaller.writeObject(obj);marshaller.finish();上面的例子中,通过调用marshaller的start方法开始序列化,然后调用marshaller.writeObject写入对象。最后调用marshaller.finish结束序列化。整个序列化代码如下:publicvoidmarshallingWrite(StringfileName,Objectobj)throwsIOException{//使用river作为编组方法MarshallerFactorymarshallerFactory=Marshalling.getProvidedMarshallerFactory("river");//创建编组配置MarshallingConfigurationconfiguration=newMarshallingConfiguration();//使用版本号4configuration.setVersion(4);finalMarshallermarshaller=marshallerFactory.createMarshaller(configuration);try(FileOutputStreamos=newFileOutputStream(fileName)){marshaller.start(Marshalling.createByteOutput(os));marshaller.writeObject(obj);marshaller.finish();}}publicstaticvoidmain(String[]args)throwsIOException{MarshallingWriterwriter=newMarshallingWriter();Studentstudent=newStudent("jack",18,"一年级");作家。编组写入(“/tmp/marshall.txt”,学生);}非常简洁明了注意这里我们序列化了一个Student对象,这个对象必须实现java.io.Serializable接口,否则会抛出如下类型的异常:Exceptioninthread"main"java.io.NotSerializableException:atorg.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:274)在org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:58)在org。jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:111)接下来就是反序列化序列化的逆动作了。代码很简单,直接上代码:publicvoidmarshallingRead(StringfileName)throwsIOException,ClassNotFoundException{//使用river协议创建一个MarshallerFactoryMarshallerFactorymarshallerFactory=Marshalling.getProvidedMarshallerFactory("river");//创建配置文件MarshallingConfigurationconfiguration=newMarshallingConfig();//使用版本号4configuration.setVersion(4);finalUnmarshallerunmarshaller=marshallerFactory.createUnmarshaller(configuration);try(FileInputStreamis=newFileInputStream(fileName)){unmarshaller.start(Marshalling.createByteInput(is));学生student=(Student)unmarshaller.readObject();log.info("学生:{}",学生);unmarshaller.finish();}}publicstaticvoidmain(String[]args)throwsIOException,ClassNotFoundException{MarshallingReaderreader=newMarshallingReader();reader.marshallingRead("/tmp/marshall.txt");}运行上面的代码,我们可能会得到如下输出:[main]INFOc.f.marshalling.MarshallingReader-student:Student(name=jack,age=18,className=firstgrade)可见对象序列化成功读。以上就是JBossMarshalling的基本使用。通常对于我们程序员来说,这个基本的用法就足够了。除非你有复杂的序列化需求,比如在序列化过程中需要替换对象中的密码,否则这个需求可以使用我们前面提到的ObjectResolver来实现。本文示例可参考:learn-netty4本文已收录于http://www.flydean.com/17-jboss-marshalling/最通俗的解读,最深刻的干货,最简洁的教程,很多你不知道的小技巧等你来发现!欢迎关注我的公众号:《程序那些事儿》,懂技术,更懂你!