FastJson源码解析:序列化(1.1.45.android)

本解析主要以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());
}

FastJson源码解析:序列化(1.1.45.android)_第1张图片

你可能感兴趣的:(开源项目源码)