GSON源码解析

Posted 流云易采

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GSON源码解析相关的知识,希望对你有一定的参考价值。

把之前做的笔记又重新整理了一下,发现简单只看了GSON的解析流程; 1、GSON的两种解析使用方式: 1)直接利用GSON中默认的反射机制来解析:
Gson gson1 = new Gson();
gson1.fromJson(str, Data.class);
2)利用自定义的TypeAdapter来解析:

// Builder模式
GsonBuilder gsonBuilder = new GsonBuilder();
// 注册自定义的Adapter;
gsonBuilder.registerTypeAdapter(Data.class, new TypeAdapter<Data>() 
    // 由对象组装成json
    @Override
    public void write(JsonWriter out, Data value) throws IOException 
    

    // 解析成对应类对象
    @Override
    public Data read(JsonReader in) throws IOException 
        return null;
    
.nullSafe());
gson = gsonBuilder.create();
两种方式的区别前者主要使用 ReflectiveTypeAdapterFactory通过反射机制来getField,setField;后者自定义了一个TypeAdapter,重写了read方法,该方法会根据自己定义返回一个解析好的类对象,因此可以自己控制解析的输出;


2、首先来看GSON是怎样区别使用两种解析TypeAdapter的:

GsonBuilder#registerTypeAdapter:

private final List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
// GSONBuilder.java
public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) 
    $Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
            || typeAdapter instanceof JsonDeserializer<?>
            || typeAdapter instanceof InstanceCreator<?>
            || typeAdapter instanceof TypeAdapter<?>);
    if (typeAdapter instanceof InstanceCreator<?>) 
        instanceCreators.put(type, (InstanceCreator) typeAdapter);
    
    // 解析原生类型
    if (typeAdapter instanceof JsonSerializer<?> || typeAdapter instanceof JsonDeserializer<?>) 
        TypeToken<?> typeToken = TypeToken.get(type);
        factories.add(TreeTypeAdapter.newFactoryWithMatchRawType(typeToken, typeAdapter));
    
    // 解析自定义的类
    if (typeAdapter instanceof TypeAdapter<?>) 
        // 创建一个TypeAdapterFactory,添加到一个List中保存
        factories.add(TypeAdapters.newFactory(TypeToken.get(type), (TypeAdapter) typeAdapter));
    
    return this;
将自定义的adapter的封装成TypeAdapterFactory对象,添加到一个List -- 中保存factories;后面将会看到TypeAdapterFactory的主要作用提供一个create方法,判断Type对应的TypeAdapter对象。

GsonBuilder#create:

public Gson create() 
    List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
    // 将所有的factorie添加到factories中传递给新建的Gson对象
    factories.addAll(this.factories);
    // 进行reverse,可以看到后添加的自定义Adapter将会放到最前面
    Collections.reverse(factories);
    factories.addAll(this.hierarchyFactories);
    addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, factories);

    return new Gson(excluder, fieldNamingPolicy, instanceCreators,
            serializeNulls, complexMapKeySerialization,
            generateNonExecutableJson, escapehtmlChars, prettyPrinting,
            serializeSpecialFloatingPointValues, longSerializationPolicy, factories);
Builder模式,创建一个GSON对象,可以看到这里将GsonBuilder中定义的factories添加到Gson的factories形参中;添加之前进行一次reverse,所以最后添加到TypeAdapter会反转到链表的最前面;


再来看Gson的构造函数:

3、Gson:

Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingPolicy,
     final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
     boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
     boolean prettyPrinting, boolean serializeSpecialFloatingPointValues,
     LongSerializationPolicy longSerializationPolicy,
     List<TypeAdapterFactory> typeAdapterFactories) 
    .......

    List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();

    // built-in type adapters that cannot be overridden
    factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
    factories.add(ObjectTypeAdapter.FACTORY);

    // the excluder must precede all adapters that handle user-defined types
    factories.add(excluder);

    // 自定义的TypeAdapter
    factories.addAll(typeAdapterFactories);

    // type adapters for basic platform types
    // 这里一次性添加所有系统中可能用到的所有types对应的Adapter
    factories.add(TypeAdapters.STRING_FACTORY);
    factories.add(TypeAdapters.INTEGER_FACTORY);
    factories.add(TypeAdapters.BOOLEAN_FACTORY);
    factories.add(TypeAdapters.BYTE_FACTORY);
    factories.add(TypeAdapters.SHORT_FACTORY);
    factories.add(TypeAdapters.newFactory(long.class, Long.class,
            longAdapter(longSerializationPolicy)));
    factories.add(TypeAdapters.newFactory(double.class, Double.class,
            doubleAdapter(serializeSpecialFloatingPointValues)));
    factories.add(TypeAdapters.newFactory(float.class, Float.class,
            floatAdapter(serializeSpecialFloatingPointValues)));
    .......
    factories.add(TypeAdapters.ENUM_FACTORY);
    factories.add(TypeAdapters.CLASS_FACTORY);

    // 这里便对应着自定义类时默认使用的ReflectiveTypeAdapterFactory
    factories.add(new CollectionTypeAdapterFactory(constructorConstructor));
    factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));
    factories.add(new ReflectiveTypeAdapterFactory(
            constructorConstructor, fieldNamingPolicy, excluder));

    this.factories = Collections.unmodifiableList(factories);
这里添加了用户定义的TypeAdapter(注意是放在链表的前面);然后添加系统中可能会用到的基本类型对应的TypeAdpater(如String,Integer等);对于用户自定义的类,则使用 ReflectiveTypeAdapterFactory ,放在链表的最后;

来看解析过程:

4、Gson.fromJson:

public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException 
    Object object = fromJson(json, (Type) classOfT);
    // 这里进行类型转换
    return Primitives.wrap(classOfT).cast(object);


public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException 
    if (json == null) 
        return null;
    
    StringReader reader = new StringReader(json);
    T target = (T) fromJson(reader, typeOfT);
    return target;


public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException 
    JsonReader jsonReader = new JsonReader(json);
    T object = (T) fromJson(jsonReader, typeOfT);
    assertFullConsumption(object, jsonReader);
    return object;


public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException 
    boolean isEmpty = true;
    boolean oldLenient = reader.isLenient();
    reader.setLenient(true);
    try 
        reader.peek();
        isEmpty = false;
        // 根据Type类型获取对应的解析Adapter
        TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
        TypeAdapter<T> typeAdapter = getAdapter(typeToken);
        
        // 执行TypeAdapter的read方法进行解析;可以看到如果是自定义的TypeAdapter,则会直接返回重写read方法中的返回值
        T object = typeAdapter.read(reader);
        return object;
     catch (EOFException e) 
  /*
   * For compatibility with JSON 1.5 and earlier, we return null for empty
   * documents instead of throwing.
   */
        if (isEmpty) 
            return null;
        
        throw new JsonSyntaxException(e);
     catch (IllegalStateException e) 
        throw new JsonSyntaxException(e);
     catch (IOException e) 
        // TODO(inder): Figure out whether it is indeed right to rethrow this as JsonSyntaxException
        throw new JsonSyntaxException(e);
     finally 
        reader.setLenient(oldLenient);
    
最后来到的解析函数中可以看到,基本的解析逻辑就是,根据Type类型获取对应的解析TypeAdapter,然后调用该 TypeAdapter的read方法进行解析,得到返回值。


先来看如何获得对应TypeAdapter:

5、Gson#getAdapter:

private final ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>> calls
        = new ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>>();
public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) 
    TypeAdapter<?> cached = typeTokenCache.get(type);
    if (cached != null) 
        return (TypeAdapter<T>) cached;
    

    Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get();
    boolean requiresThreadLocalCleanup = false;
    if (threadCalls == null) 
        // 如果当前线程不存在,则创建一个新的
        threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();
        calls.set(threadCalls);
        requiresThreadLocalCleanup = true;
    

    // the key and value type parameters always agree
    // 判断该Type类型是否已经保存
    FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type);
    if (ongoingCall != null) 
        return ongoingCall;
    

    try 
        FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();
        threadCalls.put(type, call);

        // 遍历factories中保存的所有factory
        for (TypeAdapterFactory factory : factories) 
            // TypeAdapterFactory的作用是将TypeAdapter同TypeToken组合到一起;
            // 当type匹配时,返回已创建对象,否则返回null;所以可以通过判断返回值是否为null,来判断类型是否匹配
            // 见附二
            TypeAdapter<T> candidate = factory.create(this, type);
            if (candidate != null) 
                // 设置Delegate
                call.setDelegate(candidate);
                typeTokenCache.put(type, candidate);
                return candidate;
            
        
        throw new IllegalArgumentException("GSON cannot handle " + type);
     finally 
        threadCalls.remove(type);

        if (requiresThreadLocalCleanup) 
            calls.remove();
        
    

附一、 FutureTypeAdapter

// FutureTypeAdapter是对TypeAdapter的一个封装类,其实际工作委托给内部的delegate对象进行操作
static class FutureTypeAdapter<T> extends TypeAdapter<T> 
    private TypeAdapter<T> delegate;

    public void setDelegate(TypeAdapter<T> typeAdapter) 
        if (delegate != null) 
            throw new AssertionError();
        
        delegate = typeAdapter;
    

    @Override public T read(JsonReader in) throws IOException 
        if (delegate == null) 
            throw new IllegalStateException();
        
        return delegate.read(in);
    

    @Override public void write(JsonWriter out, T value) throws IOException 
        if (delegate == null) 
            throw new IllegalStateException();
        
        delegate.write(out, value);
    

附二、TypeAdapterFactory:

public static <TT> TypeAdapterFactory newFactory(
        final TypeToken<TT> type, final TypeAdapter<TT> typeAdapter) 
    return new TypeAdapterFactory() 
        @SuppressWarnings("unchecked") // we use a runtime check to make sure the 'T's equal
        public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) 
            return typeToken.equals(type) ? (TypeAdapter<T>) typeAdapter : null;
        
    ;
自定义的TypeAdapter直接调用其read方法即可;来看ReflectiveTypeAdapterFactory的使用原理:

6、ReflectiveTypeAdapterFactory

public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory 
    private final ConstructorConstructor constructorConstructor;
    private final FieldNamingStrategy fieldNamingPolicy;
    private final Excluder excluder;

    public ReflectiveTypeAdapterFactory(ConstructorConstructor constructorConstructor,
                                        FieldNamingStrategy fieldNamingPolicy, Excluder excluder) 
        this.constructorConstructor = constructorConstructor;
        this.fieldNamingPolicy = fieldNamingPolicy;
        this.excluder = excluder;
    

    // 匹配Adapter的时候,返回的Adapter
    public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) 
        Class<? super T> raw = type.getRawType();

        if (!Object.class.isAssignableFrom(raw)) 
            return null; // it's a primitive!
        

        // 创建一个Adapter,用来对应之前的通过type查找对应的TypeAdapter操作
        ObjectConstructor<T> constructor = constructorConstructor.get(type);
        return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
    
截取 ReflectiveTypeAdapterFactory中的其中一部分,其中constructorConstructor用来通过反射机制构造实例;getBoundFields用来获取一个BoundFields,BoundFields将Field的name和一个自定义的BoundFields联系到一起,其实创建该Type的实例是通过BoundFields中重写的read方法来实现的。

static abstract class BoundField 
    final String name;
    final boolean serialized;
    final boolean deserialized;

    protected BoundField(String name, boolean serialized, boolean deserialized) 
        this.name = name;
        this.serialized = serialized;
        this.deserialized = deserialized;
    

    abstract void write(JsonWriter writer, Object value) throws IOException, IllegalAccessException;
    abstract void read(JsonReader reader, Object value) throws IOException, IllegalAccessException;

1)先来看constructorConstructor:

public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) 
    final Type type = typeToken.getType();
    final Class<? super T> rawType = typeToken.getRawType();

    // first try an instance creator

    @SuppressWarnings("unchecked") // types must agree
    final InstanceCreator<T> typeCreator = (InstanceCreator<T>) instanceCreators.get(type);
    if (typeCreator != null) 
        return new ObjectConstructor<T>() 
            public T construct() 
                return typeCreator.createInstance(type);
            
        ;
    

    // Next try raw type match for instance creators
    @SuppressWarnings("unchecked") // types must agree
    final InstanceCreator<T> rawTypeCreator =
            (InstanceCreator<T>) instanceCreators.get(rawType);
    if (rawTypeCreator != null) 
        return new ObjectConstructor<T>() 
            public T construct() 
                return rawTypeCreator.createInstance(type);
            
        ;
    

    // 创建一个默认构造器,用来创建实例
    ObjectConstructor<T> defaultConstructor = newDefaultConstructor(rawType);
    if (defaultConstructor != null) 
        return defaultConstructor;
    

    ObjectConstructor<T> defaultImplementation = newDefaultImplementationConstructor(type, rawType);
    if (defaultImplementation != null) 
        return defaultImplementation;
    

    // finally try unsafe
    return newUnsafeAllocator(type, rawType);


// 获取该Class的默认构造器,通过newInstance创建一个实例对象
private <T> ObjectConstructor<T> newDefaultConstructor(Class<? super T> rawType) 
    try 
        final Constructor<? super T> constructor = rawType.getDeclaredConstructor();
        if (!constructor.isAccessible()) 
            constructor.setAccessible(true);
        
        return new ObjectConstructor<T>() 
            @SuppressWarnings("unchecked") // T is the same raw type as is requested
            public T construct() 
                try 
                    Object[] args = null;
                    return (T) constructor.newInstance(args);
                 catch (InstantiationException e) 
                    ..........
                
            
        ;
     catch (NoSuchMethodException e) 
        return null;
    
重点看下面的 newDefaultConstructor,它提供了一个ObjectConstructor实例,该对象中有个construct方法,在解析过程中将会调用来创建一个T实例instance;由上可以,通过获取该Class的构造函数,然后调用默认构造函数的newInstance来创建一个实例。


2)创建BoundFields:

private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) 
    Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();
    // 如果数据类型是Interface的话,直接返回
    if (raw.isInterface()) 
        return result;
    

    Type declaredType = type.getType();
    while (raw != Object.class) 
        // 获得该类的所有Field
        Field[] fields = raw.getDeclaredFields();
        // 遍历所有Field
        for (Field field : fields) 
            // 判断是否能够序列化
            boolean serialize = excludeField(field, true);
            boolean deserialize = excludeField(field, false);
            if (!serialize && !deserialize) 
                continue;
            
            // 访问Field
            field.setAccessible(true);
            Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());
            // 创建BoundField,将Field的name和boundField绑定到一起
            BoundField boundField = createBoundField(context, field, getFieldName(field),
                    TypeToken.get(fieldType), serialize, deserialize);
            //
            BoundField previous = result.put(boundField.name, boundField);
            if (previous != null) 
                throw new IllegalArgumentException(declaredType
                        + " declares multiple JSON fields named " + previous.name);
            
        
        // 获取父类,重复上述操作
        type = TypeToken.get($Gson$Types.resolve(type.getType(), raw, raw.getGenericSuperclass()));
        raw = type.getRawType();
    
    return result;
通过getField获得该类的所有Field,然后由Field信息创建(createBoundField)一个BoundField,并通过HashMap将两者绑定到一起,便于查询;

来看 createBoundField:

private ReflectiveTypeAdapterFactory.BoundField createBoundField(
        final Gson context, final Field field, final String name,
        final TypeToken<?> fieldType, boolean serialize, boolean deserialize) 
    final boolean isPrimitive = Primitives.isPrimitive(fieldType.getRawType());

    // special casing primitives here saves ~5% on android...
    return new ReflectiveTypeAdapterFactory.BoundField(name, serialize, deserialize) 
        // 根据fieldType获得相应的TypeAdapter
        final TypeAdapter<?> typeAdapter = context.getAdapter(fieldType);

        @SuppressWarnings("unchecked", "rawtypes") // the type adapter and field type always agree
        @Override
        void write(JsonWriter writer, Object value) throws IOException, IllegalAccessException 
            Object fieldValue = field.get(value);
            TypeAdapter t = new TypeAdapterRuntimeTypeWrapper(context, this.typeAdapter, fieldType.getType());
            t.write(writer, fieldValue);
        

        @Override
        void read(JsonReader reader, Object value) throws IOException, IllegalAccessException 
            // 进而调用对应Type的TypeAdapter去实现
            Object fieldValue = typeAdapter.read(reader);
            if (fieldValue != null || !isPrimitive) 
                field.set(value, fieldValue);
            
        
    ;
这里创建一个BoundField实例,并且重写了read,write方法;从后面的TypeAdapter,可以看到这些的作用;


3) ReflectiveTypeAdapterFactory的内部类Adapter:

public static final class Adapter<T> extends TypeAdapter<T> 
    private final ObjectConstructor<T> constructor;
    private final Map<String, BoundField> boundFields;

    private Adapter(ObjectConstructor<T> constructor, Map<String, BoundField> boundFields) 
        this.constructor = constructor;
        this.boundFields = boundFields;
    

    @Override
    public T read(JsonReader in) throws IOException 
        // 为空值,直接返回
        if (in.peek() == JsonToken.NULL) 
            in.nextNull();
            return null;
        

        T instance = constructor.construct();

        try 
            in.beginObject();
            while (in.hasNext()) 
                String name = in.nextName();
                // boundFields是个HashMap,这里通过Field的name获取对应的boundFields
                BoundField field = boundFields.get(name);
                if (field == null || !field.deserialized) 
                    in.skipValue();
                 else 
                    // 最终的对象创建逻辑在boundField中的read中实现;
                    field.read(in, instance);
                
            
         catch (IllegalStateException e) 
            throw new JsonSyntaxException(e);
         catch (IllegalAccessException e) 
            throw new AssertionError(e);
        
        in.endObject();
        return instance;
    

    @Override
    public void write(JsonWriter out, T value) throws IOException 
        if (value == null) 
            out.nullValue();
            return;
        

        out.beginObject();
        try 
            for (BoundField boundField : boundFields.values()) 
                if (boundField.serialized) 
                    out.name(boundField.name);
                    boundField.write(out, value);
                
            
         catch (IllegalAccessException e) 
            throw new AssertionError();
        
        out.endObject();
    
可以看到这里解析逻辑,即调用前面所述的constructor创建一个instance,然后遍历jsonReader,通过读取其中的name,查找对应的FieldBounds,然后调用FieldBounds中的read方法;再回到FieldBounds中的read方法,可以看到,其可以看做一个递归实现了,继续查找该Field的类型对应的Adapter,然后调用该TypeAdpter去创建相应对象,最后进行返回。


具体的解析逻辑分析完毕,主要通过Type找到对应的TypeAdapter,如果有自定义的,则直接调用自定义Adpter的read方法;否则,使用可以看到,均是反射来实现,通过newInstance来获取实例,通过getDeclaredFields来获取Field信息;其主要工作解析原理还没有具体分析:

其主要的解析原理在JsonReader中,因为GSON中涉及到蛮多泛型、数组的打包处理,所以还要理清楚Type,、ParameterizedType、GenericArrayType、TypeVariable、WildcardType这些类的关系和概念。

以上是关于GSON源码解析的主要内容,如果未能解决你的问题,请参考以下文章

GSON源码解析

Gson解析Json

解析工具Gson源码读后感,真实项目开发经验总结

Retrofit Gson解析空字符串的问题

Gson全解析(下)-Gson性能分析

当列表的各个项目使用Retrofit和Gson的格式不同时,如何解析json列表?