零 前期准备
0 FBI WARNING
文章异常啰嗦且绕弯。
1 版本
Gson 版本 : gson 2.8.5
IDE : idea 2018.3
2 Gson 简介
Gson 是谷歌开源的 java json 解析工具。市场上同类的开源产品还有 Fastjson、Jackson、json-lib 等。
其实几款产品的差别都很细微,Gson 有谷歌的信仰加成,所以在这里进行一次源码分析。
3 Bean Demo
package ioc;
/**
* java bean
*/
public class Person {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
4 main 方法
import com.google.gson.Gson;
public class JsonTest {
public static void main(String[] args){
// 示例 json 字符串
String json =
“{” +
” \”name\”: \”zhangsan\”,” +
” \”age\”: 11″ +
“}”;
// 初始化解析器
Gson gson = new Gson();
//json to bean
Person person = gson.fromJson(json,Person.class);
System.out.println(person.getName());
System.out.println(person.getAge());
//bean to json
String json2 = gson.toJson(person);
System.out.println(json2);
}
}
一 初始化 Gson 解析器
1 Gson 构造方法
该 part 的起点:
Gson gson = new Gson();
追踪 Gson 的无参构造器:
//Gson.class
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());
}
继续追踪:
//Gson.class
Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingStrategy,
final 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) {
// 排除器,在序列化对象的时候会根据使用者设置的规则排除一些数据
// 排除策略需要使用者自行实现 ExclusionStrategy 接口来制定
this.excluder = excluder;
//fieldNamingStrategy 负责命名规则的确定 (比如 大驼峰命名、小驼峰命名、下划线命名 等)
// 选择不同的 fieldNamingStrategy 会在输出 json 字符串的时候把字段名称转成不同的命名形式
// 此处的值可以直接选择 FieldNamingPolicy 枚举类中的已经存储的策略,也可以自行实现 FieldNamingStrategy 接口
// 此处默认为 FieldNamingPolicy.IDENTITY,即不改变
this.fieldNamingStrategy = fieldNamingStrategy;
//instanceCreators 是一个用来存储实现了 InstanceCreator 接口的对象的 map
// 每一个 InstanceCreator 的实现类用来反射获取一种特定类型的 bean 对象
//InstanceCreator 在 Gson 中没有实现类,使用者可以自行定制
// 此处为空 map
this.instanceCreators = instanceCreators;
//ConstructorConstructor 用来统一调度 instanceCreators
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
//serializeNulls 是一个 boolean 类型的对象,用以表示是否支持空对象的序列化
// 此处传入的是 DEFAULT_SERIALIZE_NULLS,值为 false,是一个定义在 Gson 中的常量
this.serializeNulls = serializeNulls;
// 将 Map 序列化的过程中,会存在一个问题,即 Map 的 key 值是一个复杂对象 (java bean 等)
// 如果 complexMapKeySerialization 设置为 false,则直接调用对象的 toString() 方法获取字符串
// 设置为 true 的情况下会去尝试解析此对象,一般情况下要配合特定的 TypeAdapter 使用
// 默认为 false
this.complexMapKeySerialization = complexMapKeySerialization;
// 是否要生成不可执行的 json
// 默认为 false
this.generateNonExecutableJson = generateNonExecutableGson;
// 是否对 html 进行编码,即对部分符号进行转义 (=、<、> 等)
// 默认为 true
this.htmlSafe = htmlSafe;
// 在输出的时候格式化 json
// 默认为 false
this.prettyPrinting = prettyPrinting;
// 设置 json 的自定义标准
// 默认 false,即为 json 标准的数据格式
this.lenient = lenient;
// 用于支持 float 类型的特殊值,比如 Infinity(无穷大) 或 -Infinity(负无穷大) 等
// 默认为 false
this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues;
// 设置对 long 类型的变量,是解析成字符串还是解析为 long 类型
// 默认为解析成 long 类型
this.longSerializationPolicy = longSerializationPolicy;
// 以下三行用于设置日期格式和时间格式
//datePattern 是日期和时间的字符串格式表达,在此处为 null
//dateStyle 与 timeStyle 为日期和时间格式的编码
// 以 int 常量形式存放在 java.text.DateFormat 中
// 此处均为默认值
// 需要注意的是默认情况下 Gson 的日期解析不太符合国人的习惯
this.datePattern = datePattern;
this.dateStyle = dateStyle;
this.timeStyle = timeStyle;
// 此处为空
this.builderFactories = builderFactories;
// 此处为空
this.builderHierarchyFactories = builderHierarchyFactories;
//TypeAdapter 是一个接口,用于序列化和反序列化某种特定的类型
//TypeAdapterFactory 是 TypeAdapter 的包装类
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
//TypeAdapters 是 TypeAdapter 和 TypeAdapterFactory 的通用工具类
// 处理 JsonElement 类型对象的 TypeAdapterFactory
//JsonElement 是 Gson 工具包中的一个类
factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
// 处理 Object 类型对象的 TypeAdapterFactory
factories.add(ObjectTypeAdapter.FACTORY);
//excluder 是一个省略了类型的 TypeAdapterFactory
// 根据官方注释,excluder 需要先于所有使用者自定义的 TypeAdapterFactory 去执行
factories.add(excluder);
// 使用者自定义的 TypeAdapterFactory
factories.addAll(factoriesToBeAdded);
// 处理 String 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.STRING_FACTORY);
// 处理 Integer / int 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.INTEGER_FACTORY);
// 处理 Boolean / boolean 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.BOOLEAN_FACTORY);
// 处理 Byte / byte 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.BYTE_FACTORY);
// 处理 Short / short 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.SHORT_FACTORY);
// 处理 Long / long 类型对象的 TypeAdapterFactory
TypeAdapter<Number> longAdapter = longAdapter(longSerializationPolicy);
factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter));
// 处理 Double / double 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.newFactory(double.class, Double.class,
doubleAdapter(serializeSpecialFloatingPointValues)));
// 处理 Float / float 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.newFactory(float.class, Float.class,
floatAdapter(serializeSpecialFloatingPointValues)));
// 处理 Number 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.NUMBER_FACTORY);
// 处理 AtomicInteger 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY);
// 处理 AtomicBoolean 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY);
// 处理 AtomicBoolean 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter)));
// 处理 AtomicLongArray 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter)));
// 处理 AtomicIntegerArray 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_FACTORY);
// 处理 Character / char 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.CHARACTER_FACTORY);
// 处理 StringBuilder 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.STRING_BUILDER_FACTORY);
// 处理 StringBuffer 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.STRING_BUFFER_FACTORY);
// 处理 BigDecimal 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL));
// 处理 BigInteger 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER));
// 处理 URL 类型对象的 TypeAdapterFactory
//java.net.URL
factories.add(TypeAdapters.URL_FACTORY);
// 处理 URI 类型对象的 TypeAdapterFactory
//java.net.URI
factories.add(TypeAdapters.URI_FACTORY);
// 处理 UUID 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.UUID_FACTORY);
// 处理 Currency 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.CURRENCY_FACTORY);
// 处理 Locale 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.LOCALE_FACTORY);
// 处理 InetAddress 类型对象的 TypeAdapterFactory
//java.net.InetAddress
factories.add(TypeAdapters.INET_ADDRESS_FACTORY);
// 处理 BitSet 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.BIT_SET_FACTORY);
// 处理 Date 类型对象的 TypeAdapterFactory
//java.util.Date
factories.add(DateTypeAdapter.FACTORY);
// 处理 Calendar 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.CALENDAR_FACTORY);
// 处理 Time 类型对象的 TypeAdapterFactory
factories.add(TimeTypeAdapter.FACTORY);
// 处理 Date 类型对象的 TypeAdapterFactory
//java.sql.Date
factories.add(SqlDateTypeAdapter.FACTORY);
// 处理 Timestamp 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.TIMESTAMP_FACTORY);
// 处理 Array 类型对象的 TypeAdapterFactory
factories.add(ArrayTypeAdapter.FACTORY);
// 处理 Class 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.CLASS_FACTORY);
// 处理 Collection 类型对象的 TypeAdapterFactory
factories.add(new CollectionTypeAdapterFactory(constructorConstructor));
// 处理 Map 类型对象的 TypeAdapterFactory
// 会受到 complexMapKeySerialization 的影响
factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));
// 处理 JsonAdapter 类型对象的 TypeAdapterFactory
//JsonAdapter 是一个 Gson 中的注解
this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);
factories.add(jsonAdapterFactory);
// 处理 Enum 类型对象的 TypeAdapterFactory
factories.add(TypeAdapters.ENUM_FACTORY);
// 反射分解对象的 TypeAdapterFactory
factories.add(new ReflectiveTypeAdapterFactory(
constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));
this.factories = Collections.unmodifiableList(factories);
}
从这里可以看出,Gson 的初始化时期提供了非常丰富的设置选项。
2 GsonBuilder
设置 Gson 的这些选项需要通过 GsonBuilder:
Gson gson = new GsonBuilder()
// 以下方法均为设置 excluder
// 设置版本号
.setVersion(1)
// 设置忽略某种修饰词修饰的变量
// 此处忽略 protected 修饰的变量
.excludeFieldsWithModifiers(Modifier.PROTECTED)
// 设置使用 Expose 注解,用于忽略某个字段
// 默认情况下是不使用 Expose 注解的
.excludeFieldsWithoutExposeAnnotation()
// 设置不序列化内部类
.disableInnerClassSerialization()
// 批量添加序列化时使用的排除策略
// 此方法为不定参方法
.setExclusionStrategies(exclusionStrategy)
// 添加一个序列化时使用的排除策略
.addSerializationExclusionStrategy(exclusionStrategy)
// 添加一个反序列化时使用的排除策略
.addDeserializationExclusionStrategy(exclusionStrategy)
// 本质上以下三个方法均为设置 TypeAdapter
.registerTypeAdapter(String.class, TypeAdapters.STRING)
.registerTypeAdapterFactory(TypeAdapters.STRING_FACTORY)
.registerTypeHierarchyAdapter(String.class, TypeAdapters.STRING)
// 设置 dateStyle、datePattern、timeStyle
.setDateFormat(“yyyy-MM-dd HH:mm:ss”)
.setDateFormat(DateFormat.DATE_FIELD)
.setDateFormat(DateFormat.DATE_FIELD,DateFormat.AM_PM_FIELD)
// 以下两个方法本质上是一样的,均为设置 fieldNamingPolicy 属性
.setFieldNamingPolicy(FieldNamingPolicy.IDENTITY)
.setFieldNamingStrategy(FieldNamingPolicy.IDENTITY)
// 设置 complexMapKeySerialization = true
.enableComplexMapKeySerialization()
// 设置 longSerializationPolicy = LongSerializationPolicy.STRING
// 即 long 类型的数据在序列化的时候会转成 String
.setLongSerializationPolicy(LongSerializationPolicy.STRING)
// 设置 serializeNulls = true
.serializeNulls()
// 设置 prettyPrinting = true
.setPrettyPrinting()
// 设置 generateNonExecutableJson = true
.generateNonExecutableJson()
// 设置 lenient = true
.setLenient()
// 设置 escapeHtmlChars = false
.disableHtmlEscaping()
// 设置 serializeSpecialFloatingPointValues = true
.serializeSpecialFloatingPointValues()
// 创建解析器对象
.create();
3 Excluder
在上述设置中,有一大块是关于排除器 excluder 的设置。excluder 的实现逻辑依赖 ExclusionStrategy 的自定义实现类,追踪一下 ExclusionStrategy 接口:
// 实现
public interface ExclusionStrategy {
// 设置忽略的变量,需要传入 FieldAttributes
//FieldAttributes 是在 Gson 中定义的 Field 的包装类
public boolean shouldSkipField(FieldAttributes f);
// 设置要忽略的 class
public boolean shouldSkipClass(Class<?> clazz);
}
fieldNamingPolicy 则需要 FieldNamingStrategy 的自定义实现类,追踪一下 FieldNamingStrategy 接口:
public interface FieldNamingStrategy {
// 在这个方法中实现自定义的命名规则
public String translateName(Field f);
}
FieldNamingPolicy 是一个实现了 FieldNamingStrategy 接口的枚举类,其中实现了多套 translateName(…) 方法可供选择。
二 TypeAdapter 和 TypeAdapterFactory
在 Gson 中封装了不同类型的读写的业务组装类是各个 TypeAdapter(适配器),这里先来关注一下其具体实现。
1 父类与接口
先来看一下 TypeAdapterFactory 接口:
public interface TypeAdapterFactory {
// 只有一个方法,用于根据解析器和变量类型来创建 TypeAdapter
<T> TypeAdapter<T> create(Gson gson, TypeToken<T> type);
}
再来看一下 TypeAdapter 抽象类:
public abstract class TypeAdapter<T> {
// 写入方法,主要的指挥 JsonWriter 进行业务处理
public abstract void write(JsonWriter out, T value) throws IOException;
// 读取方法,主要是指挥 JsonReader 进行业务操作
public abstract T read(JsonReader in) throws IOException;
// 该抽象类中还提供了其它的方法,在此例中没有用到,暂时忽略
}
2 StringTypeAdapter
关注一下下列这行代码:
factories.add(TypeAdapters.STRING_FACTORY);
factories 是一个列表,来追踪一下 TypeAdapters.STRING_FACTORY:
//TypeAdapters.class
public static final TypeAdapterFactory STRING_FACTORY = newFactory(String.class, STRING);
先来看一下定义在 TypeAdapters 中的 STRING 变量:
//TypeAdapters.class
public static final TypeAdapter<String> STRING = new TypeAdapter<String>() {
// 此方法用于反序列化时读取值
@Override
public String read(JsonReader in) throws IOException {
//in.peek() 方法会获取到最新的 JsonReader 操作指令,并转换成下一个要操作的字符类型
// 在后面的 part 里还会提到
JsonToken peek = in.peek();
// 读取到 null
if (peek == JsonToken.NULL) {
in.nextNull();
return null;
}
// 读取到 boolean 类型的值
if (peek == JsonToken.BOOLEAN) {
return Boolean.toString(in.nextBoolean());
}
// 除了 null 和 boolean 之外,都视作 String 进行返回
return in.nextString();
}
// 此方法用于序列化时写入值
@Override
public void write(JsonWriter out, String value) throws IOException {
out.value(value);
}
};
继续追踪 newFactory(…) 方法:
//TypeAdapters.class
public static <TT> TypeAdapterFactory newFactory(final Class<TT> type, final TypeAdapter<TT> typeAdapter) {
return new TypeAdapterFactory() {
@SuppressWarnings(“unchecked”)
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
//typeToken.getRawType() 会获取到这个 TypeToken 所需要的
return typeToken.getRawType() == type ? (TypeAdapter<T>) typeAdapter : null;
}
// 常规的重新 toString() 方法
@Override
public String toString() {
return “Factory[type=” + type.getName() + “,adapter=” + typeAdapter + “]”;
}
};
}
从这里可以看出,TypeAdapterFactory 本质上只是 TypeAdapter 的包装类,只是做一个类型的判定工作,如果判定为相同,就会返回传入的 TypeAdapter。
一般的类型的 TypeAdpter 的操作逻辑都比较类似,不赘述了。
2 ReflectiveTypeAdapter
对于一般的自定义类,比如使用者自定义的 java bean 等,并非 jdk 自带的基本数据类型,就都需要 ReflectiveTypeAdapter 来进行解析。
先来看一下 ReflectiveTypeAdapterFactory 的 create() 方法:
//ReflectiveTypeAdapterFactory.class
public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) {
Class<? super T> raw = type.getRawType();
// 要确保 type 中获取出来的 class 的类型是 Object 的子类
// 如果不是的话就代表这是基本类型,基本类型的解析不应该使用该适配器
// 所以返回 null
if (!Object.class.isAssignableFrom(raw)) {
return null;
}
//constructor 用于反射创建对象
ObjectConstructor<T> constructor = constructorConstructor.get(type);
//Adapter 是 ReflectiveTypeAdapterFactory 的静态内部类,继承了 TypeAdapter
return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
}
来继续追踪一下 Adapter 的主要方法:
public static final class Adapter<T> extends TypeAdapter<T> {
// 此处 read(…) 和 write(…) 的代码比较类似
// 主要步骤是通过反射创建出对象,并抓取其所有的变量,逐个存入
public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
// 调用构造器反射创建出对象
T instance = constructor.construct();
// 以下代码是 Gson 读出字符串中的部分,并用反射填入到对象中的过程
try {
in.beginObject();
while (in.hasNext()) {
String name = in.nextName();
//BoundField 是 Gson 对 jdk 中的 Field 类的增强
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;
}
public void write(JsonWriter out, T value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
out.beginObject();
// 以下是 Gson 从对象中获取到数据并写成字符串的过程
try {
for (BoundField boundField : boundFields.values()) {
if (boundField.writeField(value)) {
out.name(boundField.name);
boundField.write(out, value);
}
}
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
out.endObject();
}
}
具体的步骤其实是对 java 反射的深度定制化应用,不展开了。
以上过程在 JsonReader 和 JsonWriter 的应用中会有类似展开。至于 JsonReader 和 JsonWriter 会在后续进行追踪。
To Be Continued …