源碼分析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序列化和反序列化的核心流程就分析的差不多了,如果還想繼續深研各個適配器和幫助組件是怎麼工作的,可以下載源碼繼續查看閱讀。

發佈了7 篇原創文章 · 獲贊 2 · 訪問量 4937
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章