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