2021SC@SDUSC
特定序列化实现解析
以MapSerializer序列化为例的分析
按照代码的顺序第一个分析到Map序列化器,内部调用write:
public void write(JSONSerializer serializer
, Object object
, Object fieldName
, Type fieldType
, int features) throws IOException {
write(serializer, object, fieldName, fieldType, features, false);
}
在其最终调用的write方法中:
if ((out.features & mapSortFieldMask) != 0 || (features & mapSortFieldMask) != 0) {
if (map instanceof JSONObject) {
map = ((JSONObject) map).getInnerMap();
}
if ((!(map instanceof SortedMap)) && !(map instanceof LinkedHashMap)) {
try {
map = new TreeMap(map);
} catch (Exception ex) {
// skip
}
}
}
首先JSONObject包装HashMap或者LinkedHashMap
serializer.setContext(parent, object, fieldName, 0);
try {
if (!unwrapped) {
out.write('{');
}
serializer.incrementIndent();
Class<?> preClazz = null;
ObjectSerializer preWriter = null;
boolean first = true;
if (out.isEnabled(SerializerFeature.WriteClassName)) {
String typeKey = serializer.config.typeKey;
Class<?> mapClass = map.getClass();
boolean containsKey = (mapClass == JSONObject.class || mapClass == HashMap.class || mapClass == LinkedHashMap.class)
&& map.containsKey(typeKey);
/** 序列化的map不包含key=@type或者自定义值,则输出map的类名 */
if (!containsKey) {
out.writeFieldName(typeKey);
out.writeString(object.getClass().getName());
first = false;
}
}
然后创建当前新的序列化context ;
然后在接下来的循环中开始遍历filter来确定哪些输出哪些不输出:
遍历JSONSerializer的PropertyPreFilter拦截器,拦截key是否输出:
遍历JSONSerializer的PropertyPreFilter拦截器,拦截key是否输出
List<PropertyPreFilter> preFilters = serializer.propertyPreFilters;
if (preFilters != null && preFilters.size() > 0) {
if (entryKey == null || entryKey instanceof String) {
if (!this.applyName(serializer, object, (String) entryKey)) {
continue;
}
} else if (entryKey.getClass().isPrimitive() || entryKey instanceof Number) {
String strKey = JSON.toJSONString(entryKey);
if (!this.applyName(serializer, object, strKey)) {
continue;
}
}
}
遍历PropertyPreFilter拦截器,拦截key是否输出 :
List<PropertyPreFilter> preFilters = this.propertyPreFilters;
if (preFilters != null && preFilters.size() > 0) {
if (entryKey == null || entryKey instanceof String) {
if (!this.applyName(serializer, object, (String) entryKey)) {
continue;
}
} else if (entryKey.getClass().isPrimitive() || entryKey instanceof Number) {
String strKey = JSON.toJSONString(entryKey);
if (!this.applyName(serializer, object, strKey)) {
continue;
}
}
}
遍历JSONSerializer的PropertyFilter拦截器,拦截key是否输出
List<PropertyFilter> propertyFilters = serializer.propertyFilters;
if (propertyFilters != null && propertyFilters.size() > 0) {
if (entryKey == null || entryKey instanceof String) {
if (!this.apply(serializer, object, (String) entryKey, value)) {
continue;
}
} else if (entryKey.getClass().isPrimitive() || entryKey instanceof Number) {
String strKey = JSON.toJSONString(entryKey);
if (!this.apply(serializer, object, strKey, value)) {
continue;
}
}
}
遍历PropertyFilter拦截器,拦截key是否输出:
List<PropertyFilter> propertyFilters = this.propertyFilters;
if (propertyFilters != null && propertyFilters.size() > 0) {
if (entryKey == null || entryKey instanceof String) {
if (!this.apply(serializer, object, (String) entryKey, value)) {
continue;
}
} else if (entryKey.getClass().isPrimitive() || entryKey instanceof Number) {
String strKey = JSON.toJSONString(entryKey);
if (!this.apply(serializer, object, strKey, value)) {
continue;
}
}
}
遍历JSONSerializer的NameFilter拦截器,适用于key字符别名串转换:
List<NameFilter> nameFilters = serializer.nameFilters;
if (nameFilters != null && nameFilters.size() > 0) {
if (entryKey == null || entryKey instanceof String) {
entryKey = this.processKey(serializer, object, (String) entryKey, value);
} else if (entryKey.getClass().isPrimitive() || entryKey instanceof Number) {
String strKey = JSON.toJSONString(entryKey);
entryKey = this.processKey(serializer, object, strKey, value);
}
}
遍历NameFilter拦截器,适用于key字符串别名转换:
List<NameFilter> nameFilters = this.nameFilters;
if (nameFilters != null && nameFilters.size() > 0) {
if (entryKey == null || entryKey instanceof String) {
entryKey = this.processKey(serializer, object, (String) entryKey, value);
} else if (entryKey.getClass().isPrimitive() || entryKey instanceof Number) {
String strKey = JSON.toJSONString(entryKey);
entryKey = this.processKey(serializer, object, strKey, value);
}
}
处理map序列化value拦截器, ValueFilter 和 ContextValueFilter:
if (entryKey == null || entryKey instanceof String) {
value = this.processValue(serializer, null, object, (String) entryKey, value);
} else {
boolean objectOrArray = entryKey instanceof Map || entryKey instanceof Collection;
if (!objectOrArray) {
String strKey = JSON.toJSONString(entryKey);
value = this.processValue(serializer, null, object, strKey, value);
}
}
然后,开启WriteNonStringKeyAsString, 将key做一次json串转换:
if (out.isEnabled(NON_STRINGKEY_AS_STRING) && !(entryKey instanceof Enum)) {
String strEntryKey = JSON.toJSONString(entryKey);
serializer.write(strEntryKey);
} else {
serializer.write(entryKey);
}
out.write(':');
map序列化实现方法主要做了以下几件事情:
处理对象引用,使用jdk的IdentityHashMap类严格判断对象严格相等。
针对map的key和value执行拦截器操作。
针对value的类型,查找value的class类型序列化输出。
序列化map处理引用的逻辑在 com.alibaba.fastjson.serializer.JSONSerializer#writeReference ,带分析的源码如下:
public void writeReference(Object object) {
SerialContext context = this.context;
Object current = context.object;
/** 如果输出引用就是自己this, ref值为 @ */
if (object == current) {
out.write("{\"$ref\":\"@\"}");
return;
}
SerialContext parentContext = context.parent;
/** 如果输出引用就是父引用, ref值为 .. */
if (parentContext != null) {
if (object == parentContext.object) {
out.write("{\"$ref\":\"..\"}");
return;
}
}
SerialContext rootContext = context;
/** 查找最顶层序列化context */
for (;;) {
if (rootContext.parent == null) {
break;
}
rootContext = rootContext.parent;
}
if (object == rootContext.object) {
/** 如果最顶层引用就是自己this, ref值为 $*/
out.write("{\"$ref\":\"$\"}");
} else {
/** 常规java对象引用,直接输出 */
out.write("{\"$ref\":\"");
out.write(references.get(object).toString());
out.write("\"}");
}
}
ListSerializer序列化
ListSerializer的序列化和map的序列化类似:
public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
throws IOException {
boolean writeClassName = serializer.out.isEnabled(SerializerFeature.WriteClassName)
|| SerializerFeature.isEnabled(features, SerializerFeature.WriteClassName);
SerializeWriter out = serializer.out;
Type elementType = null;
if (writeClassName) {
/** 获取泛型字段真实类型 */
elementType = TypeUtils.getCollectionItemType(fieldType);
}
if (object == null) {
/** 如果集合对象为空并且开启WriteNullListAsEmpty特性, 输出[] */
out.writeNull(SerializerFeature.WriteNullListAsEmpty);
return;
}
List<?> list = (List<?>) object;
if (list.size() == 0) {
/** 如果集合对象元素为0, 输出[] */
out.append("[]");
return;
}
/** 创建当前新的序列化context */
SerialContext context = serializer.context;
serializer.setContext(context, object, fieldName, 0);
ObjectSerializer itemSerializer = null;
try {
/** 判断是否开启json格式化 */
if (out.isEnabled(SerializerFeature.PrettyFormat)) {
out.append('[');
serializer.incrementIndent();
int i = 0;
for (Object item : list) {
if (i != 0) {
out.append(',');
}
serializer.println();
if (item != null) {
/** 如果存在引用,输出元素引用信息 */
if (serializer.containsReference(item)) {
serializer.writeReference(item);
} else {
/** 通过元素包含的类型查找序列化实例 */
itemSerializer = serializer.getObjectWriter(item.getClass());
SerialContext itemContext = new SerialContext(context, object, fieldName, 0, 0);
serializer.context = itemContext;
/** 根据具体序列化实例输出 */
itemSerializer.write(serializer, item, i, elementType, features);
}
} else {
serializer.out.writeNull();
}
i++;
}
serializer.decrementIdent();
serializer.println();
out.append(']');
return;
}
out.append('[');
for (int i = 0, size = list.size(); i < size; ++i) {
Object item = list.get(i);
if (i != 0) {
out.append(',');
}
if (item == null) {
out.append("null");
} else {
Class<?> clazz = item.getClass();
if (clazz == Integer.class) {
/** 元素类型如果是整数,直接输出 */
out.writeInt(((Integer) item).intValue());
} else if (clazz == Long.class) {
/** 元素类型如果是长整数,直接输出并判断是否追加类型L */
long val = ((Long) item).longValue();
if (writeClassName) {
out.writeLong(val);
out.write('L');
} else {
out.writeLong(val);
}
} else {
if ((SerializerFeature.DisableCircularReferenceDetect.mask & features) != 0){
/** 如果禁用循环引用检查,根据元素类型查找序列化实例输出 */
itemSerializer = serializer.getObjectWriter(item.getClass());
itemSerializer.write(serializer, item, i, elementType, features);
}else {
if (!out.disableCircularReferenceDetect) {
/** 如果没有禁用循环引用检查,创建新的序列化上下文 */
SerialContext itemContext = new SerialContext(context, object, fieldName, 0, 0);
serializer.context = itemContext;
}
if (serializer.containsReference(item)) {
/** 处理对象引用 */
serializer.writeReference(item);
} else {
/** 根据集合类型查找序列化实例处理,JavaBeanSerializer后面单独分析 */
itemSerializer = serializer.getObjectWriter(item.getClass());
if ((SerializerFeature.WriteClassName.mask & features) != 0
&& itemSerializer instanceof JavaBeanSerializer)
{
JavaBeanSerializer javaBeanSerializer = (JavaBeanSerializer) itemSerializer;
javaBeanSerializer.writeNoneASM(serializer, item, i, elementType, features);
} else {
itemSerializer.write(serializer, item, i, elementType, features);
}
}
}
}
}
}
out.append(']');
} finally {
serializer.context = context;
}
}
ListSerializer序列化主要判断是否需要格式化json输出,对整型和长整型进行特殊取值,如果是对象类型根据class类别查找序列化实例处理,和hessian2源码实现原理类似。