本解析主要以JSON.toJSONString(Object)这个方法作为入口。以HashSet《POJO》作为例子。
#1
String s = JSON.toJSONString(beanSet);
以这个方法为入口,上面的beanSet为一个以POJO类为泛型的hashSet。
#2
public static final String toJSONString(Object object) {
return toJSONString(object, new SerializerFeature[0]);
}
public static final String toJSONString(Object object, SerializerFeature... features) {
//这里构建的过程中会将默认的SerializerFeature 加入的writer中
//详见下一个代码块#3
SerializeWriter out = new SerializeWriter();
try {
JSONSerializer serializer = new JSONSerializer(out);
for (SerializerFeature feature : features) {
serializer.config(feature, true);
}
//序列化的核心方法在此
//详见后面的代码块#5
serializer.write(object);
return out.toString();
} finally {
out.close();
}
}
下面是SerializeWriter(继承自writer) 构造器代码
#3
public SerializeWriter(Writer writer){
this.writer = writer;
//这里会有一些默认的feature 后面会用到
this.features = JSON.DEFAULT_GENERATE_FEATURE;
SoftReference ref = bufLocal.get();
if (ref != null) {
//buf是这个writer的缓存 char数组
buf = ref.get();
//bufLocal是一个threadLocal类型
bufLocal.set(null);
}
if (buf == null) {
buf = new char[1024];
}
}
关于默认的features,在JSON中,静态初始化了这个成员变量,如下:
#4
public static int DEFAULT_GENERATE_FEATURE;
static {
int features = 0;
features |= SerializerFeature.QuoteFieldNames.getMask();
features |= SerializerFeature.SkipTransientField.getMask();
features |= SerializerFeature.WriteEnumUsingToString.getMask();
features |= SerializerFeature.SortField.getMask();
// features |=
// SerializerFeature.WriteSlashAsSpecial.getMask();
DEFAULT_GENERATE_FEATURE = features;
}
由此可知,默认已经加入了QuoteFieldNames, SkipTransientField, WriteEnumUsingToString, SortField四个feature。
#5
public final void write(Object object) {
if (object == null) {
out.writeNull();
return;
}
Class> clazz = object.getClass();
//第一处核心代码在此
ObjectSerializer writer = getObjectWriter(clazz);
try {
//第二处核心逻辑在这里,这个代码被包住了
writer.write(this, object, null, null);
} catch (IOException e) {
//此处抛出异常
throw new JSONException(e.getMessage(), e);
}
}
#6
public ObjectSerializer getObjectWriter(Class> clazz) {
ObjectSerializer writer = config.get(clazz);
if (writer == null) {
if (Map.class.isAssignableFrom(clazz)) {
config.put(clazz, MapSerializer.instance);
} else if (List.class.isAssignableFrom(clazz)) {
config.put(clazz, ListSerializer.instance);
} else if (Collection.class.isAssignableFrom(clazz)) {
//我们的逻辑(hashSet),应该进入了这里
config.put(clazz, CollectionSerializer.instance);
} else if (Date.class.isAssignableFrom(clazz)) {
config.put(clazz, DateSerializer.instance);
} else if (JSONAware.class.isAssignableFrom(clazz)) {
config.put(clazz, JSONAwareSerializer.instance);
} else if (JSONSerializable.class.isAssignableFrom(clazz)) {
config.put(clazz, JSONSerializableSerializer.instance);
} else if (JSONStreamAware.class.isAssignableFrom(clazz)) {
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;
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;
}
}
if (isCglibProxy || isJavassistProxy) {
Class> superClazz = clazz.getSuperclass();
ObjectSerializer superWriter = getObjectWriter(superClazz);
config.put(clazz, superWriter);
return superWriter;
}
if (Proxy.isProxyClass(clazz)) {
config.put(clazz, config.createJavaBeanSerializer(clazz));
} else {
//对于一般的POJO,应该进入了这里,见#8
config.put(clazz, config.createJavaBeanSerializer(clazz));
}
}
writer = config.get(clazz);
}
return writer;
}
#7:CollectionSerializer序列化器的writer方法
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType) throws IOException {
SerializeWriter out = serializer.getWriter();
if (object == null) {
if (out.isEnabled(SerializerFeature.WriteNullListAsEmpty)) {
out.write("[]");
} else {
out.writeNull();
}
return;
}
Type elementType = null;
if (serializer.isEnabled(SerializerFeature.WriteClassName)) {
if (fieldType instanceof ParameterizedType) {
ParameterizedType param = (ParameterizedType) fieldType;
elementType = param.getActualTypeArguments()[0];
}
}
Collection> collection = (Collection>) object;
SerialContext context = serializer.getContext();
serializer.setContext(context, object, fieldName, 0);
if (serializer.isEnabled(SerializerFeature.WriteClassName)) {
if (HashSet.class == collection.getClass()) {
out.append("Set");
} else if (TreeSet.class == collection.getClass()) {
out.append("TreeSet");
}
}
try {
int i = 0;
out.append('[');
for (Object item : collection) {
if (i++ != 0) {
out.append(',');
}
if (item == null) {
out.writeNull();
continue;
}
Class> clazz = item.getClass();
if (clazz == Integer.class) {
out.writeInt(((Integer) item).intValue());
continue;
}
if (clazz == Long.class) {
out.writeLong(((Long) item).longValue());
if (out.isEnabled(SerializerFeature.WriteClassName)) {
out.write('L');
}
continue;
}
//最终如果是集合内部一个Object,会调用对应的ObjectSerializer,这就回到了#6中的getObjectWriter代码,实际上会得到一个JavaBeanSerializer实例
ObjectSerializer itemSerializer = serializer.getObjectWriter(clazz);
itemSerializer.write(serializer, item, i - 1, elementType);
}
out.append(']');
} finally {
serializer.setContext(context);
}
}
#8 SerializeConfig对于一般JavaBean的Serializer
public ObjectSerializer createJavaBeanSerializer(Class> clazz) {
return new JavaBeanSerializer(clazz);
}
#9 JavaBeanSerializer最终的构造器
public JavaBeanSerializer(Class> clazz, Map aliasMap){
this.features = TypeUtils.getSerializeFeatures(clazz);
//下面是两个代码块
{
List getterList = new ArrayList();
//核心逻辑在computeGetters这个方法中,获取了所有的getter,因为Android没有内省框架,所以这里是fastJson自行实现的
List fieldInfoList = TypeUtils.computeGetters(clazz, aliasMap, false);
for (FieldInfo fieldInfo : fieldInfoList) {
//这里将fieldInfo通过createFieldSerializer转换为FieldSerializer
getterList.add(createFieldSerializer(fieldInfo));
}
//最终放在getter这个FieldSerializer数组里
getters = getterList.toArray(new FieldSerializer[getterList.size()]);
}
{
List getterList = new ArrayList();
List fieldInfoList = TypeUtils.computeGetters(clazz, aliasMap, true);
for (FieldInfo fieldInfo : fieldInfoList) {
getterList.add(createFieldSerializer(fieldInfo));
}
sortedGetters = getterList.toArray(new FieldSerializer[getterList.size()]);
}
}
#10 实际上返回的是ObjectFieldSerializer
public FieldSerializer createFieldSerializer(FieldInfo fieldInfo) {
Class> clazz = fieldInfo.getFieldClass();
//感觉这里写的有问题,是否应该是clazz.isAssignedFrom(Number.class)??,不然这个NumberFieldSerializer没可能用的上的吧?
if (clazz == Number.class) {
return new NumberFieldSerializer(fieldInfo);
}
return new ObjectFieldSerializer(fieldInfo);
}
#11 ObjectFieldSerializer的构造器:
public ObjectFieldSerializer(FieldInfo fieldInfo){
super(fieldInfo);
JSONField annotation = fieldInfo.getAnnotation(JSONField.class);
if (annotation != null) {
format = annotation.format();
if (format.trim().length() == 0) {
format = null;
}
//这里会将JSONField annotation中feature的内容初始化为bool
for (SerializerFeature feature : annotation.serialzeFeatures()) {
if (feature == SerializerFeature.WriteNullNumberAsZero) {
writeNumberAsZero = true;
} else if (feature == SerializerFeature.WriteNullStringAsEmpty) {
writeNullStringAsEmpty = true;
} else if (feature == SerializerFeature.WriteNullBooleanAsFalse) {
writeNullBooleanAsFalse = true;
} else if (feature == SerializerFeature.WriteNullListAsEmpty) {
writeNullListAsEmpty = true;
} else if (feature == SerializerFeature.WriteEnumUsingToString) {
writeEnumUsingToString = true;
}
}
}
}
#12 run too far 回到JavaBeanSerializer的write方法
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType) throws IOException {
SerializeWriter out = serializer.getWriter();
//见下#13,如果为空,直接过进入这里,写入字符串:null
if (object == null) {
out.writeNull();
return;
}
if (writeReference(serializer, object)) {
return;
}
final FieldSerializer[] getters;
if (out.isEnabled(SerializerFeature.SortField)) {
getters = this.sortedGetters;
} else {
getters = this.getters;
}
SerialContext parent = serializer.getContext();
serializer.setContext(parent, object, fieldName, features);
final boolean writeAsArray = isWriteAsArray(serializer);
try {
final char startSeperator = writeAsArray ? '[' : '{';
final char endSeperator = writeAsArray ? ']' : '}';
out.append(startSeperator);
if (getters.length > 0 && out.isEnabled(SerializerFeature.PrettyFormat)) {
serializer.incrementIndent();
serializer.println();
}
boolean commaFlag = false;
if (isWriteClassName(serializer, object, fieldType, fieldName)) {
Class> objClass = object.getClass();
if (objClass != fieldType) {
out.writeFieldName(JSON.DEFAULT_TYPE_KEY);
serializer.write(object.getClass());
commaFlag = true;
}
}
char seperator = commaFlag ? ',' : '\0';
char newSeperator = FilterUtils.writeBefore(serializer, object, seperator);
commaFlag = newSeperator == ',';
for (int i = 0; i < getters.length; ++i) {
FieldSerializer fieldSerializer = getters[i];
//这里会跳过Transient字段
if (serializer.isEnabled(SerializerFeature.SkipTransientField)) {
Field field = fieldSerializer.getField();
if (field != null) {
if (Modifier.isTransient(field.getModifiers())) {
continue;
}
}
}
if (!FilterUtils.applyName(serializer, object, fieldSerializer.getName())) {
continue;
}
//这里拿出propertyValue
Object propertyValue = fieldSerializer.getPropertyValue(object);
if (!FilterUtils.apply(serializer, object, fieldSerializer.getName(), propertyValue)) {
continue;
}
String key = FilterUtils.processKey(serializer, object, fieldSerializer.getName(), propertyValue);
Object originalValue = propertyValue;
propertyValue = FilterUtils.processValue(serializer, object, fieldSerializer.getName(), propertyValue);
if (propertyValue == null && !writeAsArray) {
if ((!fieldSerializer.isWriteNull())
&& (!serializer.isEnabled(SerializerFeature.WriteMapNullValue))) {
continue;
}
}
//注意propertyValue 这个字段,这里如果配置了为默认值的时候不写入,会进入这个if
if (propertyValue != null && serializer.isEnabled(SerializerFeature.NotWriteDefaultValue)) {
Class> fieldCLass = fieldSerializer.fieldInfo.getFieldClass();
if (fieldCLass == byte.class && propertyValue instanceof Byte && ((Byte)propertyValue).byteValue() == 0) {
continue;
} else if (fieldCLass == short.class && propertyValue instanceof Short && ((Short)propertyValue).shortValue() == 0) {
continue;
} else if (fieldCLass == int.class && propertyValue instanceof Integer && ((Integer)propertyValue).intValue() == 0) {
continue;
} else if (fieldCLass == long.class && propertyValue instanceof Long && ((Long)propertyValue).longValue() == 0L) {
continue;
} else if (fieldCLass == float.class && propertyValue instanceof Float && ((Float)propertyValue).floatValue() == 0F) {
continue;
} else if (fieldCLass == double.class && propertyValue instanceof Double && ((Double)propertyValue).doubleValue() == 0D) {
continue;
} else if (fieldCLass == boolean.class && propertyValue instanceof Boolean && !((Boolean)propertyValue).booleanValue()) {
continue;
}
}
if (commaFlag) {
out.append(',');
if (out.isEnabled(SerializerFeature.PrettyFormat)) {
serializer.println();
}
}
if (key != fieldSerializer.getName()) {
if (!writeAsArray) {
out.writeFieldName(key);
}
serializer.write(propertyValue);
} else if (originalValue != propertyValue) {
if (!writeAsArray) {
fieldSerializer.writePrefix(serializer);
}
serializer.write(propertyValue);
} else {
if (!writeAsArray) {
fieldSerializer.writeProperty(serializer, propertyValue);
} else {
fieldSerializer.writeValue(serializer, propertyValue);
}
}
//这个表示逗号是否写入
commaFlag = true;
}
FilterUtils.writeAfter(serializer, object, commaFlag ? ',' : '\0');
if (getters.length > 0 && out.isEnabled(SerializerFeature.PrettyFormat)) {
serializer.decrementIdent();
serializer.println();
}
out.append(endSeperator);
} catch (Exception e) {
throw new JSONException("write javaBean error", e);
} finally {
serializer.setContext(parent);
}
}
/#13 ObjectFieldSerializer.writeValue方法,最终对于Field会进入这里
@Override
public void writeValue(JSONSerializer serializer, Object propertyValue) throws Exception {
if (format != null) {
serializer.writeWithFormat(propertyValue, format);
return;
}
if (runtimeInfo == null) {
Class> runtimeFieldClass;
if (propertyValue == null) {
runtimeFieldClass = this.fieldInfo.getFieldClass();
} else {
runtimeFieldClass = propertyValue.getClass();
}
//这里对于Field字段如何写入分配了对应的ObjectSerializer,一般应该是JavaBeanSerializer
ObjectSerializer fieldSerializer = serializer.getObjectWriter(runtimeFieldClass);
runtimeInfo = new RuntimeSerializerInfo(fieldSerializer, runtimeFieldClass);
}
final RuntimeSerializerInfo runtimeInfo = this.runtimeInfo;
//字段值为空的时候的处理
if (propertyValue == null) {
if (writeNumberAsZero && Number.class.isAssignableFrom(runtimeInfo.runtimeFieldClass)) {
serializer.getWriter().write('0');
return;
} else if (writeNullStringAsEmpty && String.class == runtimeInfo.runtimeFieldClass) {
serializer.getWriter().write("\"\"");
return;
} else if (writeNullBooleanAsFalse && Boolean.class == runtimeInfo.runtimeFieldClass) {
serializer.getWriter().write("false");
return;
} else if (writeNullListAsEmpty && Collection.class.isAssignableFrom(runtimeInfo.runtimeFieldClass)) {
serializer.getWriter().write("[]");
return;
}
//如果没有任何配置 则应该为是JavaBeanSerializer来处理,见#12
runtimeInfo.fieldSerializer.write(serializer, null, fieldInfo.getName(), null);
return;
}
if (writeEnumUsingToString == true && runtimeInfo.runtimeFieldClass.isEnum()) {
serializer.getWriter().writeString(((Enum>) propertyValue).name());
return;
}
Class> valueClass = propertyValue.getClass();
if (valueClass == runtimeInfo.runtimeFieldClass) {
runtimeInfo.fieldSerializer.write(serializer, propertyValue, fieldInfo.getName(), fieldInfo.getFieldType());
return;
}
ObjectSerializer valueSerializer = serializer.getObjectWriter(valueClass);
valueSerializer.write(serializer, propertyValue, fieldInfo.getName(), fieldInfo.getFieldType());
}