源码分析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序列化和反序列化的核心流程就分析的差不多了,如果还想继续深研各个适配器和帮助组件是怎么工作的,可以下载源码继续查看阅读。