Gson源码解析
Posted microhex
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gson源码解析相关的知识,希望对你有一定的参考价值。
文章目录
基础了解
最近在解决一个Json解析时,把Gson原理过了一遍。Gson是Google开发的Json解析库,当然这种轮子市面上比较多,也不一一列举了。今天主要来聊聊Gson源码,是如何解析一个Json对象,然后按照葫芦画瓢,将一个Java对象如何序列化成 Json对象。
几个重要的概念
在分析Gson源码之前,首先需要在脑子中需要有这样几个概念,或者简单一点,我们先定义一个我们自己的抽象类:
1. 属性赋值/序列化
// 属性操作逻辑
abstract FieldOpertator
// 对象属性的读取
abstract void read();
// 对象属性的写入
abstract void write();
对于FieldOpertator
来讲,可以理解为Java对象的属性赋值器/序列化,比如下面一个Java对象:
public class Person
public String name;
public int age;
public String[] address;
那么Person
对应的属性为name
,age
和address
, 那么就分别存在对应的三个FieldOpertator
来负责和序列化解析name
,age
和address
.
2. Java类型适配器
这个说法可能会比较抽象,但是看到了上面的属性赋值/序列化之后,应该就会有一个大致的概念,Person
的name
是String
型的,age
是int
型的,address
是数组类型的,那么代码中会怎么识别,应该怎么知道它们分别是什么类型的呢?所以此时需要顶一个Java类型适配器,根据不同的java类型进行不同的适配,然后在不同的类型适配器里面做相关的工作即可。
public abstract class TypeAdapter<T>
abstract void read(T t);
abstract void write(T t)
此时我们需要定义一个接口,通过Java属性的不同类型来获取到不同的 TypeAdapter
,这里我们使用工厂方法获取接口逻辑。
public interface TypeAdapterFactory
<T> TypeAdapter<T> create(Type type);
这里的Type
是 java类中的Class
的顶级接口,可以理解为:
System.out.println(String.class.getTypeName());
System.out.println(List[].class.getTypeName());
//---out----
//java.lang.String
//java.util.List[]
3. JsonReader
给我们一段字符串,我们需要一个工具类来进行读取,比如我们需要读取的下一个字段为Int型数据,或者String型数据,这个工具类需要非常聪明的替我们完成要求。这里就不深入去说了,因为不是我们现在的主要目标。
源码分析
1. Gson初始化
首先我们在new Gson()
的时候,首先需要知道我们干了些啥:
public Gson()
this(Excluder.DEFAULT,
FieldNamingPolicy.IDENTITY,
Collections.<Type,
InstanceCreator<?>>emptyMap(),
DEFAULT_SERIALIZE_NULLS,
DEFAULT_COMPLEX_MAP_KEYS,
DEFAULT_JSON_NON_EXECUTABLE,
DEFAULT_ESCAPE_html,
DEFAULT_PRETTY_PRINT,
DEFAULT_LENIENT,
DEFAULT_SPECIALIZE_FLOAT_VALUES,
LongSerializationPolicy.DEFAULT,
null,
DateFormat.DEFAULT, DateFormat.DEFAULT,
Collections.<TypeAdapterFactory>emptyList(), Collections.<TypeAdapterFactory>emptyList(),
Collections.<TypeAdapterFactory>emptyList());
这么多参数,其实我自己看着也挺懵逼的,还是那句老话,等到用到的时候,我们再去看它们吧。但是有一段代码需要注意:
// 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);
这里需要解释一下,Gson在初始化时,内部就注册了大量的了 TypeAdapter
,即根据不同的类型,选择自定义的TypeAdapter
进行属性的解析和注入。
2. 源码分析
String jsonStr = "'name' : 'Steven', 'age' : 18, 'address' : []";
Person p = new Gson().fromJson(jsonStr, Person.class);
现在来看一下源码:
public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException
Object object = fromJson(json, (Type) classOfT);
return Primitives.wrap(classOfT).cast(object);
直接深入:
public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException
if (json == null)
return null;
StringReader reader = new StringReader(json);
T target = (T) fromJson(reader, typeOfT);
return target;
这里直接出现了StringReader
,先说明它的作用,还是直接深入fromJson()
源码:
public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException
try
TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
TypeAdapter<T> typeAdapter = getAdapter(typeToken);
T object = typeAdapter.read(reader);
return object;
catch (EOFException e)
直接看 getAdapter()
:
public <T> TypeAdapter<T> getAdapter(TypeToken<T> type)
// 代码省略....只拿关键代码
// 如果存在缓存 直接从缓存中取
TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);
if (cached != null)
return (TypeAdapter<T>) cached;
try
//遍历factory
for (TypeAdapterFactory factory : factories)
TypeAdapter<T> candidate = factory.create(this, type);
if (candidate != null)
call.setDelegate(candidate);
typeTokenCache.put(type, candidate);
return candidate;
其实最主要的就是遍历factories
, 在factory.create()
中获取到我们的candidate
候选者,如果候选者为空,则继续遍历,直到找到合适的为止。
这里存在34个factory,我们大致看一下是根据什么判断候选者是否为空了吧,来一个简单的:TypeAdapters.STRING_FACTOR
return new TypeAdapterFactory()
@SuppressWarnings("unchecked") // we use a runtime check to make sure the 'T's equal
@Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken)
return typeToken.getRawType() == type ? (TypeAdapter<T>) typeAdapter : null;
由于此时我们的type
类型是Person
类型,所有返回为null,继续下一个,重复这个逻辑,到了最后只剩下ReflectiveTypeAdapterFactory
这个工厂类,看名字就知道这个反射类型的工具类:
@Override public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type)
Class<? super T> raw = type.getRawType();
ObjectConstructor<T> constructor = constructorConstructor.get(type);
return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
可以看到,这里无论如何都是会返回一个Adapter
的,这就是我们默认兜底的策略,现在来了最重要的一个方法了:getBoundFields
,来看看主要是干了些什么吧:
private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw)
Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();
Type declaredType = type.getType();
while (raw != Object.class)
//通过反射 获取到 class 的属性
Field[] fields = raw.getDeclaredFields();
for (Field field : fields)
BoundField previous = null;
for (int i = 0, size = fieldNames.size(); i < size; ++i)
String name = fieldNames.get(i);
BoundField boundField = createBoundField(context, field, name, TypeToken.get(fieldType), serialize, deserialize);
result.put(name, boundField);
type = TypeToken.get($Gson$Types.resolve(type.getType(), raw, raw.getGenericSuperclass()));
raw = type.getRawType();
return result;
这段代码主要做了以下功能:
- 获取Class的所有属性;
- 将每一个属性转化为的
BoundField
,并保存; - 获取父类的Class对象,依照步骤1,2;
- 返回包含所有
BoundField
的对象。
好了,现在我们回到代码入口处:
public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException
try
TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
TypeAdapter<T> typeAdapter = getAdapter(typeToken);
T object = typeAdapter.read(reader);
return object;
catch (EOFException e)
此时的typeAdapter
就是我们已经确定的ReflectiveTypeAdapterFactory
,现在直接看read(reader)
方法了:
@Override public T read(JsonReader in) throws IOException
// 1. 初始化对象
T instance = constructor.construct();
try
in.beginObject();
while (in.hasNext())
//2. 获取字符串中的名称
String name = in.nextName();
//3. 在刚才反射集合中通过名称查找 BoundField
BoundField field = boundFields.get(name);
if (field == null || !field.deserialized)
in.skipValue();
else
// 4. 读取数据,赋值给对象指定属性
field.read(in, instance);
catach(Exception e)
in.endObject();
return instance;
在read(reader)
方法中,基本的代码已经注释了,现在最复杂的就是注释4,读取数据,然后赋值给对象的指定属性。好了,我们直接上代码:
//注释1
final TypeAdapter<?> typeAdapter = mGson.getAdapter(fieldType<以上是关于Gson源码解析的主要内容,如果未能解决你的问题,请参考以下文章