Osheep

时光不回头,当下最重要。

Gson源码学习浅析

引用文献/文档:
[1] https://github.com/google/gson
[2] http://www.ietf.org/rfc/rfc7159.txt RFC 7159
[3] http://kb.cnblogs.com/page/515982/ 序列化与反序列化

Gson
A Java serialization/deserialization library to convert Java Objects into JSON and back[1].就如文档所说,Gson的作用是在Java对象和JSON(JavaScript Object Notation)之间做序列化/反序列化转化的类库。

关于序列化/反序列化,可参考美团的一篇技术文章[3]。

序列化
从一句简单的代码开始

String jsonBean = new Gson().toJson(bean);
  public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {
    //关键在这里,通过传入的类型信息,构造相应的TypeAdapter
    TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));
    boolean oldLenient = writer.isLenient();
    writer.setLenient(true);
    boolean oldHtmlSafe = writer.isHtmlSafe();
    writer.setHtmlSafe(htmlSafe);
    boolean oldSerializeNulls = writer.getSerializeNulls();
    writer.setSerializeNulls(serializeNulls);
    try {
      //输出,完成整个序列化过程
      ((TypeAdapter<Object>) adapter).write(writer, src);
    } catch (IOException e) {
      throw new JsonIOException(e);
    } finally {
      writer.setLenient(oldLenient);
      writer.setHtmlSafe(oldHtmlSafe);
      writer.setSerializeNulls(oldSerializeNulls);
    }
  }
TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));
//继续跟进,进入方法
  public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
    TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);
//typeTokenCache = new ConcurrentHashMap<TypeToken<?>, TypeAdapter<?>>();  typeTokenCache 是一个以TypeToken为key,TypeAdapter为value的线程安全的map
    if (cached != null) {
      return (TypeAdapter<T>) cached;
    }
    //FutureTypeAdapter 是一个代理TypeAdapter
    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
    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,根据序列化对象类型创建实例
      for (TypeAdapterFactory factory : factories) {
        TypeAdapter<T> candidate = factory.create(this, type);
        if (candidate != null) {
          //设置代理,加入缓存,从这里也可以看出构造adapter是有顺序的,先加入factories的会优先构造出Adapter
          call.setDelegate(candidate);
          typeTokenCache.put(type, candidate);
          return candidate;
        }
      }
      throw new IllegalArgumentException("GSON cannot handle " + type);
    } finally {
      threadCalls.remove(type);
      if (requiresThreadLocalCleanup) {
        calls.remove();
      }
    }
  }

通过Factory创建实例以ReflectiveTypeAdapterFactory为例(最简单的可查看ObjectTypeAdapter中的实现)

 @Override public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) {
    //获取泛型的外部类型
    Class<? super T> raw = type.getRawType();
    //raw不是Object的超类,也不是Object类,那么raw是基本类型
    if (!Object.class.isAssignableFrom(raw)) {
      return null; // it's a primitive!
    }
    //实例raw类的构造器
    ObjectConstructor<T> constructor = constructorConstructor.get(type);
    return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
  }

  private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) {
    //BoundField类有3个成员变量:成员变量名,是否序列化,是否反序列化
    Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();
    //如果raw是接口,直接返回
    if (raw.isInterface()) {
      return result;
    }
    //获取Runtime的type
    Type declaredType = type.getType();
    while (raw != Object.class) {
      //获取字段
      Field[] fields = raw.getDeclaredFields();
      for (Field field : fields) {
        //excludeField方法对SerializedName的Annotation进行处理,设置序列化的字段name
        boolean serialize = excludeField(field, true);
        boolean deserialize = excludeField(field, false);
        if (!serialize && !deserialize) {
          continue;
        }
        field.setAccessible(true);//取消访问权限限制
        //resolve方法处理了TypeVariable,GenericArrayType,ParameterizedType,该方法的实现非常复杂,$Gson$Types是一个专门处理泛型的工具类
        Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());
        List<String> fieldNames = getFieldNames(field);
        BoundField previous = null;
        for (int i = 0; i < fieldNames.size(); ++i) {
          String name = fieldNames.get(i);
          if (i != 0) serialize = false; // only serialize the default name
          //createBoundField方法处理了JsonAdapter的Annotation,创建成员变量
          BoundField boundField = createBoundField(context, field, name,
              TypeToken.get(fieldType), serialize, deserialize);
          BoundField replaced = result.put(name, boundField);
          if (previous == null) previous = replaced;
        }
        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;
  }

最终调用

((TypeAdapter<Object>) adapter).write(writer, src);//完成序列化

可以看出TypeAdapter是一个关键,正如文档所说,Converts Java objects to and from JSON. TypeAdapter的可以通过JsonAdapter的Annotation获得自定义的,也可以使用默认Gson初始化添加的。到这里就不能理解Gson初始化时factories加入了一大堆。而通过自定义TypeAdapter扩展后,不仅能提升性能,更可以介入序列化/反序列化过程。
由此不难看出序列化的过程为:

传入对象ObjectType →解析ObjectType ,生成TypeAdapter→ 调用adapter.write(writer, src);

反序列化
近期完成

点赞