fastJson序列化和反序列化流程
一、核心源码
1、SerializeWriter
该类主要用于序列化,有以下成员变量
public final class SerializeWriter extends Writer {
/**
* 储存序列化结果的字段
*/
protected char buf[];
/**
* 写入缓存的长度
*/
protected int count;
/**
* 该对象用于close时将buf绑定到线程上,避免下次重复new出
*/
private final static ThreadLocal<SoftReference<char[]>> bufLocal = new ThreadLocal<SoftReference<char[]>>();
/**
* 序列化的一些特性配置
*/
private int features;
/**
* 包装对象,支持对Writer类型包含数据的序列化
*/
private final Writer writer;
//传入Writer对象
public SerializeWriter(Writer writer){
this.writer = writer;
//默认序列化属性
this.features = JSON.DEFAULT_GENERATE_FEATURE;
//获取线程缓存buf对象
SoftReference<char[]> ref = bufLocal.get();
//获取到赋值给当前buf并清空,防止重复new出。
//由于count在关闭的时候已经等于0,所以即使buf里有数据,也不会影响当次结果
if (ref != null) {
buf = ref.get();
bufLocal.set(null);
}
if (buf == null) {
buf = new char[1024];
}
}
}
存在buf的缓存对象,自然需要具体的写入方法。下图列出了主要的写入方法
类的方法结构图
接下来我们来看默认的配置特性
JSON.DEFAULT_GENERATE_FEATURE
public abstract class JSON implements JSONStreamAware, JSONAware {
public static int DEFAULT_GENERATE_FEATURE;
static {
int features = 0;
//输出key时使用双引号
features |= SerializerFeature.QuoteFieldNames.getMask();
//跳过Transient注解的字段
features |= SerializerFeature.SkipTransientField.getMask();
//将Enum枚举转换为toString()字符串
features |= SerializerFeature.WriteEnumUsingToString.getMask();
//按字段名称排序后输出
features |= SerializerFeature.SortField.getMask();
// features |=
// com.alibaba.fastjson.serializer.SerializerFeature.WriteSlashAsSpecial.getMask();
DEFAULT_GENERATE_FEATURE = features;
}
}
二、序列化
1.序列化过程
我们从调用方法toJSONString开始,会调用
public static final String toJSONString(Object object, SerializerFeature... features) {
//详细写数据的类,存储序列化过程的数据,最后通过 out.toString()转化为json字符串
SerializeWriter out = new SerializeWriter();
try {
//Json序列化解析对象的类,解析过程中向out写入数据
JSONSerializer serializer = new JSONSerializer(out);
//向解析器添加序列化属性
for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) {
serializer.config(feature, true);
}
//解析传入的对象,保存在out中
serializer.write(object);
//将解析的结果转成String输出
return out.toString();
} finally {
out.close();
}
}
接下里我们来看JSONSerializer的write方法
public class JSONSerializer {
……
public final void write(Object object) {
//如果空对象,直接写入null字符串
if (object == null) {
out.writeNull();
return;
}
//获取到类,通过getObjectWriter(clazz)找到对应的解析器
Class<?> clazz = object.getClass();
ObjectSerializer writer = getObjectWriter(clazz);
try {
//对应序列化器执行序列化写操作
writer.write(this, object, null, null);
} catch (IOException e) {
throw new JSONException(e.getMessage(), e);
}
}
……
}
那我们来看看怎么获取对应序列化器的
public ObjectSerializer getObjectWriter(Class<?> clazz) {
//先从SerializeConfig配置中获取默认基础类型的代码序列化器
ObjectSerializer writer = config.get(clazz);
//如果未获取到,再解析对象类型,并加入配置列表当中,例如
if (writer == null) {
if (Map.class.isAssignableFrom(clazz)) {
//Map类型
config.put(clazz, MapSerializer.instance);
} else if (List.class.isAssignableFrom(clazz)) {
//List类型
config.put(clazz, ListSerializer.instance);
} else if (Collection.class.isAssignableFrom(clazz)) {
//Collection类型
config.put(clazz, CollectionSerializer.instance);
} else if (Date.class.isAssignableFrom(clazz)) {
//Date日期类型
config.put(clazz, DateSerializer.instance);
} else if (JSONAware.class.isAssignableFrom(clazz)) {
//JSONAware日期类型
config.put(clazz, JSONAwareSerializer.instance);
} else if (JSONSerializable.class.isAssignableFrom(clazz)) {
//JSONSerializable日期类型
config.put(clazz, JSONSerializableSerializer.instance);
} else if (JSONStreamAware.class.isAssignableFrom(clazz)) {
//JSONStreamAware类型
config.put(clazz, JSONStreamAwareSerializer.instance);
} else if (clazz.isEnum() || (clazz.getSuperclass() != null && clazz.getSuperclass().isEnum())) {
//枚举类型的类
config.put(clazz, EnumSerializer.instance);
} else if (clazz.isArray()) {
//数组类型
Class<?> componentType = clazz.getComponentType();
ObjectSerializer compObjectSerializer = getObjectWriter(componentType);
config.put(clazz, new ArraySerializer(componentType, compObjectSerializer));
} else if (Throwable.class.isAssignableFrom(clazz)) {
//异常类型
config.put(clazz, new ExceptionSerializer(clazz));
} else if (TimeZone.class.isAssignableFrom(clazz)) {
//市区类型
config.put(clazz, TimeZoneCodec.instance);
} else if (Charset.class.isAssignableFrom(clazz)) {
//字符编码类型
config.put(clazz, CharsetCodec.instance);
} else if (Enumeration.class.isAssignableFrom(clazz)) {
//实现了枚举接口的类
config.put(clazz, EnumerationSeriliazer.instance);
} else if (Calendar.class.isAssignableFrom(clazz)) {
//日历类型
config.put(clazz, CalendarCodec.instance);
} else {
boolean isCglibProxy = false;
boolean isJavassistProxy = false;
//判断是否是CGLIB或javassist生成的代理类
for (Class<?> item : clazz.getInterfaces()) {
if (item.getName().equals("net.sf.cglib.proxy.Factory")
|| item.getName().equals("org.springframework.cglib.proxy.Factory")) {
isCglibProxy = true;
break;
} else if (item.getName().equals("javassist.util.proxy.ProxyObject")) {
isJavassistProxy = true;
break;
}
}
//如果是CGLIB或javassist生成的代理类,就放父类的序列化器
if (isCglibProxy || isJavassistProxy) {
Class<?> superClazz = clazz.getSuperclass();
ObjectSerializer superWriter = getObjectWriter(superClazz);
config.put(clazz, superWriter);
return superWriter;
}
//不管是不是动态代理类型,都是用JavaBean序列化器
if (Proxy.isProxyClass(clazz)) {
config.put(clazz, config.createJavaBeanSerializer(clazz));
} else {
config.put(clazz, config.createJavaBeanSerializer(clazz));
}
}
//上面向config中添加了类对应的序列化器,现在获取Writer返回
writer = config.get(clazz);
}
return writer;
}
回过来看看第一行的默认配置的基础解析器
public class SerializeConfig extends IdentityHashMap<Type, ObjectSerializer> {
……
public SerializeConfig(int tableSize){
super(tableSize);
put(Boolean.class, BooleanCodec.instance);
put(Character.class, CharacterCodec.instance);
put(Byte.class, IntegerCodec.instance);
put(Short.class, IntegerCodec.instance);
put(Integer.class, IntegerCodec.instance);
put(Long.class, LongCodec.instance);
put(Float.class, FloatCodec.instance);
put(Double.class, DoubleSerializer.instance);
put(BigDecimal.class, BigDecimalCodec.instance);
put(BigInteger.class, BigIntegerCodec.instance);
put(String.class, StringCodec.instance);
put(byte[].class, ByteArraySerializer.instance);
put(short[].class, ShortArraySerializer.instance);
put(int[].class, IntArraySerializer.instance);
put(long[].class, LongArraySerializer.instance);
put(float[].class, FloatArraySerializer.instance);
put(double[].class, DoubleArraySerializer.instance);
put(boolean[].class, BooleanArraySerializer.instance);
put(char[].class, CharArraySerializer.instance);
put(Object[].class, ObjectArraySerializer.instance);
put(Class.class, ClassSerializer.instance);
put(SimpleDateFormat.class, DateFormatSerializer.instance);
put(Locale.class, LocaleCodec.instance);
put(Currency.class, CurrencyCodec.instance);
put(TimeZone.class, TimeZoneCodec.instance);
put(UUID.class, UUIDCodec.instance);
put(InetAddress.class, InetAddressCodec.instance);
put(Inet4Address.class, InetAddressCodec.instance);
put(Inet6Address.class, InetAddressCodec.instance);
put(InetSocketAddress.class, InetSocketAddressCodec.instance);
put(URI.class, URICodec.instance);
put(URL.class, URLCodec.instance);
put(Pattern.class, PatternCodec.instance);
put(Charset.class, CharsetCodec.instance);
}
……
}
三、反序列化
反序列化流程和序列化流程差不多,在这我就不过多介绍,感兴趣的同学可以继续查看源码分析,培养阅读源码的兴趣。