源码分析Gson序列化和反序列化流程

源码分析Gson序列化和反序列化流程

一、核心源码

1.核心对象— TypeAdapter

	类型适配器,里面
	public abstract class TypeAdapter<T> {
	
		/**
		 *	该方法用于toJson时写入数据序列化
		 **/
		public abstract void write(JsonWriter out, T value) throws IOException;

		/**
		  *   该方法用于fromJson读取数据反序列化
		  **/
	 	public abstract T read(JsonReader in) throws IOException;
	}

根据不同的字段类型,在Gson初始化的时候提供了List类型用于储存对应类型的TypeAdapter的工厂类。

Gson(Excluder excluder, FieldNamingStrategy fieldNamingStrategy,
      Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
      boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
      boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
      LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,
      int timeStyle, List<TypeAdapterFactory> builderFactories,
      List<TypeAdapterFactory> builderHierarchyFactories,
      List<TypeAdapterFactory> factoriesToBeAdded) {
    this.excluder = excluder;
    this.fieldNamingStrategy = fieldNamingStrategy;
    this.instanceCreators = instanceCreators;
    this.constructorConstructor = new ConstructorConstructor(instanceCreators);
    this.serializeNulls = serializeNulls;
    this.complexMapKeySerialization = complexMapKeySerialization;
    this.generateNonExecutableJson = generateNonExecutableGson;
    this.htmlSafe = htmlSafe;
    this.prettyPrinting = prettyPrinting;
    this.lenient = lenient;
    this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues;
    this.longSerializationPolicy = longSerializationPolicy;
    this.datePattern = datePattern;
    this.dateStyle = dateStyle;
    this.timeStyle = timeStyle;
    this.builderFactories = builderFactories;
    this.builderHierarchyFactories = builderHierarchyFactories;

    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);

    // users' type adapters
    factories.addAll(factoriesToBeAdded);

    // type adapters for basic platform types
    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);
    TypeAdapter<Number> longAdapter = longAdapter(longSerializationPolicy);
    factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter));
    factories.add(TypeAdapters.newFactory(double.class, Double.class,
            doubleAdapter(serializeSpecialFloatingPointValues)));
    factories.add(TypeAdapters.newFactory(float.class, Float.class,
            floatAdapter(serializeSpecialFloatingPointValues)));
    factories.add(TypeAdapters.NUMBER_FACTORY);
    factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY);
    factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY);
    factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter)));
    factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter)));
    factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_FACTORY);
    factories.add(TypeAdapters.CHARACTER_FACTORY);
    factories.add(TypeAdapters.STRING_BUILDER_FACTORY);
    factories.add(TypeAdapters.STRING_BUFFER_FACTORY);
    factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL));
    factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER));
    factories.add(TypeAdapters.URL_FACTORY);
    factories.add(TypeAdapters.URI_FACTORY);
    factories.add(TypeAdapters.UUID_FACTORY);
    factories.add(TypeAdapters.CURRENCY_FACTORY);
    factories.add(TypeAdapters.LOCALE_FACTORY);
    factories.add(TypeAdapters.INET_ADDRESS_FACTORY);
    factories.add(TypeAdapters.BIT_SET_FACTORY);
    factories.add(DateTypeAdapter.FACTORY);
    factories.add(TypeAdapters.CALENDAR_FACTORY);
    factories.add(TimeTypeAdapter.FACTORY);
    factories.add(SqlDateTypeAdapter.FACTORY);
    factories.add(TypeAdapters.TIMESTAMP_FACTORY);
    factories.add(ArrayTypeAdapter.FACTORY);
    factories.add(TypeAdapters.CLASS_FACTORY);

    // type adapters for composite and user-defined types
    factories.add(new CollectionTypeAdapterFactory(constructorConstructor));
    factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));
    this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);
    factories.add(jsonAdapterFactory);
    factories.add(TypeAdapters.ENUM_FACTORY);
    factories.add(new ReflectiveTypeAdapterFactory(
        constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));

    this.factories = Collections.unmodifiableList(factories);
  }

从上面可以看出,TypeAdapters里实例里许多不同类型的TypeAdapter和TypeAdapterFactory对象。

二、序列化

1.序列化过程

开始方法toJson,该方法有不同参数的重载类型,最终会调用到下面的核心方法

 /**
   * Writes the JSON representation of {@code src} of type {@code typeOfSrc} to
   * {@code writer}.
   * @throws JsonIOException if there was a problem writing to the writer
   */
  @SuppressWarnings("unchecked")
  public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {
    //通过type获取到对应类型的TypeAdapter的序列号适配器
    TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));
    //该参数是否是宽松的json语法规则,
    //false:会多判断double类型isNaN(非数字值)和isInfinite(正无穷大或负无穷大),如果其中一个为true,则抛出异常
    //true:宽松规则,不对这两个做校验
    boolean oldLenient = writer.isLenient();
    writer.setLenient(true);
    //是否html标签需要转义
    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);
    }
  }

接下来我们看getAdapter方法是怎么获取适配器的

public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
    //首先从缓存中查找是否有对应type的TypeAdapter,有就返回
    TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);
    if (cached != null) {
      return (TypeAdapter<T>) cached;
    }
    //calls对象是ThreadLocal类型,每个线程独有对应的适配器
    //threadCalls的key:Type,value:TypeAdapter代理的包装适配器类
    Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get();
    boolean requiresThreadLocalCleanup = false;
    //threadCalls当前线程没有就新建一个设置到当前线程的calls对象里
    if (threadCalls == null) {
      threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();
      calls.set(threadCalls);
      requiresThreadLocalCleanup = true;
    }

    // the key and value type parameters always agree
    //如果当前线程中有对应type的TypeAdapter就直接返回
    FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type);
    if (ongoingCall != null) {
      return ongoingCall;
    }
    //如果缓存里没有,线程map也没有对应的TypeAdapter,就创建
    try {
      //创建包装对象FutureTypeAdapter并加入当前线程的threadCalls
      FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();
      threadCalls.put(type, call);
      //在gson初始化的List<TypeAdapterFactory>中查找对应的TypeAdapter
      for (TypeAdapterFactory factory : factories) {
        TypeAdapter<T> candidate = factory.create(this, type);
        //如果查找到,设置给call中的代理成员对象delegate,同时设置进typeTokenCache缓存中
        if (candidate != null) {
          call.setDelegate(candidate);
          typeTokenCache.put(type, candidate);
          return candidate;
        }
      }
      throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type);
    } finally {
      //当前已经加入了缓存中,所以需要清除
      threadCalls.remove(type);

      if (requiresThreadLocalCleanup) {
        calls.remove();
      }
    }
  }

接下来我们来看看getAdapter的方法参数TypeToken

public class TypeToken<T> {
  //type对应的class类型
	final Class<? super T> rawType;
	//T对应的类型
	final Type type;
	final int hashCode;
	
	
	//由于该方法是protected类型,使用的时候需要继承创建一个子类,例如使用匿名内部类
	//例如,TypeToken<List<String>> list = new TypeToken<List<String>>() {}; 必须带有{},不能使用通配符?等
	protected TypeToken() {
      this.type = getSuperclassTypeParameter(getClass());//获取泛型T的类型
      this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);//获取type类型的Class类型
      this.hashCode = type.hashCode();
  }

   /**
    * Unsafe. Constructs a type literal manually.
    */
   @SuppressWarnings("unchecked")
   TypeToken(Type type) {
      this.type = $Gson$Types.canonicalize($Gson$Preconditions.checkNotNull(type));
      this.rawType = (Class<? super T>) $Gson$Types.getRawType(this.type);
      this.hashCode = this.type.hashCode();
   }
	……
}

接下来我们看type是怎么获取的

 /**
 * Returns the type from super class's type parameter in {@link $Gson$Types#canonicalize
 * canonical form}.
 */
static Type getSuperclassTypeParameter(Class<?> subclass) {
  //返回带泛型参数的父类型
  Type superclass = subclass.getGenericSuperclass();
  //Class类型抛出异常
  if (superclass instanceof Class) {
    throw new RuntimeException("Missing type parameter.");
  }
  //强转成泛型参数类型
  ParameterizedType parameterized = (ParameterizedType) superclass;
  //获取泛型参数的第一个的类型
  return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
}

上面讲了从调用toJson开始到开始真正开始序列化的地方,接下来会挑选一到两个类型解析器作为详解

(1)实体类序列化适配器—ReflectiveTypeAdapterFactory创建的适配器

在getAdapter方法中,通过调用factory.create(this, type)来获取TypeAdapter对象,所以从create方法入手


@Override public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) {
  Class<? super T> raw = type.getRawType();

  //检测是否是Object
  if (!Object.class.isAssignableFrom(raw)) {
    return null; // it's a primitive!
  }
  //constructorConstructor包含了实例创建器,
  ObjectConstructor<T> constructor = constructorConstructor.get(type);
  //Adapter继承TypeAdapter, 
  //getBoundFields方法主要做的事情是,type和原始类型raw,查找当前类的字段并返回Map<字段名,字段信息>
  return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
}

接下来看constructorConstructor.get怎么查找类构造方法的


 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
   //尝试从instanceCreators获取构造对象,instanceCreators是new GsonBuilder().registerTypeAdapter()中添加
   @SuppressWarnings("unchecked") // types must agree
   final InstanceCreator<T> typeCreator = (InstanceCreator<T>) instanceCreators.get(type);
   //有的话就直接返回
   if (typeCreator != null) {
     return new ObjectConstructor<T>() {
       @Override public T construct() {
         return typeCreator.createInstance(type);
       }
     };
   }

   // 接下来尝试通过原始类型rawType查找,有就返回
   @SuppressWarnings("unchecked") // types must agree
   final InstanceCreator<T> rawTypeCreator =
       (InstanceCreator<T>) instanceCreators.get(rawType);
   if (rawTypeCreator != null) {
     return new ObjectConstructor<T>() {
       @Override public T construct() {
         return rawTypeCreator.createInstance(type);
       }
     };
   }
   
   //获取没有参数的构造器
   ObjectConstructor<T> defaultConstructor = newDefaultConstructor(rawType);
   if (defaultConstructor != null) {
     return defaultConstructor;
   }
   
  //获取通用接口类型(如Map和List及其子类型)的构造函数。
   ObjectConstructor<T> defaultImplementation = newDefaultImplementationConstructor(type, rawType);
   if (defaultImplementation != null) {
     return defaultImplementation;
   }

   // 最后反射获取没有参数的构造函数,如果失败(抽象类、接口等)则抛出异常
   return newUnsafeAllocator(type, rawType);
 }

下面就到了真正的适配器操作过程


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

   Adapter(ObjectConstructor<T> constructor, Map<String, BoundField> boundFields) {
     this.constructor = constructor;
     this.boundFields = boundFields;
   }
   
   //前文有说到,用于反序列化
   @Override public T read(JsonReader in) throws IOException {
    ……
    }

   //现在我们关注当前序列化方法
   @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.writeField(value)) {
         	//写入key
           out.name(boundField.name);
           //根据字段类型,找对应的TypeAdapter继续解析value
           boundField.write(out, value);
         }
       }
     } catch (IllegalAccessException e) {
       throw new AssertionError(e);
     }
     //结束解析对象,右括号}
     out.endObject();
   }
 }
}

以上就是一个对象序列化完整的流程

三、反序列化

1.反序列化过程

原理基本和序列化一样,我们现在只关注核心逻辑

(1)fromJson
  //第一个参数,通过StringReader -> Reader -> JsonReader 包装对象,
  //第二个参数,当前反射对象对应的Type
  public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
    boolean isEmpty = true;
    //上面说的json是否宽松规则,设置为宽松解析
    boolean oldLenient = reader.isLenient();
    reader.setLenient(true);
    try {
    	//返回下一个可用字符,会抛出AssertionError版本错误
    	//内部执行doPeek(),会对当前json字符串做校验
      reader.peek();
      isEmpty = false;
      //构建类型TypeToken
      TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
      //通过getAdapter(typeToken)获取对应的解析TypeAdapter
      TypeAdapter<T> typeAdapter = getAdapter(typeToken);
      //通过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.
       */
       //如果格式通过,就返回null,如果格式未校验通过,抛出异常
      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);
    } catch (AssertionError e) {
      AssertionError error = new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage());
      error.initCause(e);
      throw error;
    } finally {
      //更改回原来的规则
      reader.setLenient(oldLenient);
    }
  }

####(2)TypeAdapter.read(以ReflectiveTypeAdapterFactory创建的适配器为例)
序列化的时候我们说到,ReflectiveTypeAdapterFactory最后创建的就是这个Adapter适配器


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

    Adapter(ObjectConstructor<T> constructor, Map<String, BoundField> boundFields) {
      this.constructor = constructor;
      this.boundFields = boundFields;
    }
    
    //现在我们关注用于反序列化
    @Override public T read(JsonReader in) throws IOException {
    	//如果读取为空直接返回null
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
        return null;
      }
	//通过构造器实例化对象
      T instance = constructor.construct();

      try {
      	  //开始解析
        in.beginObject();
        while (in.hasNext()) {
          //读取下一个key值
          String name = in.nextName();
          //在字段类型中查找当前
          BoundField field = boundFields.get(name);
          //如果当前字段不存在或者排除了反序列化,跳过
          if (field == null || !field.deserialized) {
            in.skipValue();
          } else {
          	//交给对应字段类型的解析适配器,继续去解析
            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 {
    ……
    }
}

到这里我们的Gson序列化和反序列化的核心流程就分析的差不多了,如果还想继续深研各个适配器和帮助组件是怎么工作的,可以下载源码继续查看阅读。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值