2021SC@SDUSC
目录
本篇简介
使用方式
源码分析
JSON序列化器(JSONSerializer)
序列化写入器(SerializeWriter)
总结
fastjson在1.2.11版本中,JSON类新增对OutputStream/Writer直接支持,也就是说,我们可以直接将java对象转化为对应的JSON字符/字节输出流对象输出,这样极大地提高了fastJSON在使用上的灵活性,比如,我们可以将JSON字符串直接输出到文件当中持久化保存.
本篇首先介绍字节流输出,也就是对应的writeJSONString方法的有关使用与其内部实现.
在使用前作为初学者需要注意的是:序列化的java对象必须是javaBean,javaBean不是一种技术而是一种java对象的规范,主要描述符合这些规范的java对象:
例如:
一般,我们使用该方法的简化重载方法,这个方法的描述是,静态常方法,使用JSON类调用,参数是输出流,序列化javaBean以及自定义特性(这个将放在以后详细说明),返回的是最终json字符串的长度:
使用实例1-控制台打印:
结果:
使用实例2-文件输出:
结果:
进入参数最多的重载方法中,可以看到该方法的具体实现
可以看到它初始化了两个对象,一个是SerializeWriter ,和一个JSONSerializer,且前者的对象将作为参数传递给后者的对象,紧接着,JSONSerializer对象开始对参数中的dateFormate以及filter进行处理,然后再调用write(object)处理序列化对象,然后才是writer调用writetoEx(os,charset)方法处理字符编码以及输出流,而这个方法将返回一个len作为json字符串的长度并作为最终return结果.
我们需要分析的重点就是SerializeWriter以及JSONSerializer这两个类的各自的工作以及两者间的关系,以及writer.writeToEx()方法的作用.(事实上,该方法和toJSONString方法几乎一模一样,前者最后执行了writeToEx并返回了长度,后者则是返回了String,这个我也会放到后面来说)
进入该类中,我们发现该类写在serializer目录中,是序列化操作的核心目录.这个类的作用是作为一个处理器,用于通过对象类型去寻找特定的序列化处理器以及配置序列化规则.
我们去关注其write(object)方法:
这里有一个新的类型ObjectSerializer,这是一个接口,接口中只有一个write方法,并且在源码描述中,这是一个回调方法,用于序列化特定的类型.由于ObjectSerialzer只是一个接口,所以说,具体的序列化实现还在getObjectwriter(clazz)这个方法的返回当中.而实际上,通过更底层地跟踪(这个放在下一篇中),我们发现底层使用了一个自主编写的IdentityHashMap,类似于hashmap的键值对数据结构,来存放实现了的序列化器.
所以说,这个write(object)方法事实上并非直接序列化的实现,而作用是先判断对象是否为空,然后根据对象类型查找特定的序列化处理器(使用的是config去查找),然后再使用具体的序列化器来处理该对象.
这个类实际上是一个类似于StringBuilder的类,因为json字符串的生成不可能直接使用原来的字符串拼接来实现,这样会大大降低速度,于是就有了序列化写入器.这个类提供了字符串拼接,字符串扩展的方法,主要是辅助序列化器,将序列化器中转化好的序列化数据拼接起来,而具体拼接的数据以及拼接的规则则不归该类定义.
关于这个类中唯一出现在wirte(object)方法中的writeToEx(out,charset)方法,实际上就是将最终处理好的序列化数据buf变成按特定编码的二进制字节流然后输出,而在toJSONString中则是直接返回了new String(buf,0,count).
本篇对json字节流的表层源码进行了分析(可以预见字符流也有同样的结构),了解到了其实现的一个代码结构,而关于其具体底层实现的每一个部分,我打算留在后面一点一点地分析.
总而言之,FastJson字节流输出的核心代码结构就是,由JSONSerializer组织其中的各个部分进行序列化配置,拼接,输出.