Android Gson自定义序列化行为的注入方式原理剖析
一、自定义序列化行为注入概述
1.1 注入需求与应用场景
在Android开发中,Gson默认的序列化机制有时无法满足复杂业务需求,例如:
- 对特殊数据类型(如日期、枚举)进行特定格式转换
- 隐藏或修改对象中敏感字段
- 为序列化结果添加额外元数据
- 优化复杂对象的序列化性能
通过自定义序列化行为注入,开发者能够灵活控制对象到JSON的转换过程,增强Gson的扩展性和适应性。
1.2 核心注入方式
Gson支持以下几种自定义序列化行为的注入方式:
- @JsonAdapter注解:通过注解指定自定义的
TypeAdapter类 - 实现TypeAdapter接口:直接实现
TypeAdapter处理特定类型 - TypeAdapterFactory工厂:动态创建
TypeAdapter实例 - JsonSerializer/JsonDeserializer接口:分别处理序列化和反序列化逻辑
二、@JsonAdapter注解注入原理
2.1 注解定义与作用
@JsonAdapter注解用于指定处理某个类的自定义适配器:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR})
public @interface JsonAdapter {
// 指定TypeAdapter或TypeAdapterFactory类
Class<?> value();
}
使用示例:
@JsonAdapter(DateTypeAdapter.class)
public class MyModel {
private Date createdAt;
// 其他字段...
}
2.2 注解解析流程
Gson通过JsonAdapterAnnotationTypeAdapterFactory处理@JsonAdapter注解:
final class JsonAdapterAnnotationTypeAdapterFactory implements TypeAdapterFactory {
private final ConstructorConstructor constructorConstructor;
public JsonAdapterAnnotationTypeAdapterFactory(
ConstructorConstructor constructorConstructor) {
this.constructorConstructor = constructorConstructor;
}
@SuppressWarnings("unchecked")
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
// 获取目标类型上的@JsonAdapter注解
JsonAdapter annotation = typeToken.getRawType().getAnnotation(JsonAdapter.class);
if (annotation == null) {
return null;
}
// 创建自定义TypeAdapter实例
return createTypeAdapter(
constructorConstructor, gson, typeToken, annotation);
}
private <T> TypeAdapter<T> createTypeAdapter(
ConstructorConstructor constructorConstructor,
Gson gson,
TypeToken<T> typeToken,
JsonAdapter annotation) {
Class<?> adapterClass = annotation.value();
// 处理TypeAdapter子类
if (TypeAdapter.class.isAssignableFrom(adapterClass)) {
Class<TypeAdapter<?>> typeAdapterClass =
(Class<TypeAdapter<?>>) adapterClass;
ObjectConstructor<TypeAdapter<?>> constructor =
constructorConstructor.get(TypeToken.get(typeAdapterClass));
TypeAdapter<?> typeAdapter = constructor.construct();
return (TypeAdapter<T>) typeAdapter.nullSafe();
}
// 处理JsonSerializer/Deserializer实现类
if (JsonSerializer.class.isAssignableFrom(adapterClass) ||
JsonDeserializer.class.isAssignableFrom(adapterClass)) {
Object instance = constructorConstructor.get(
TypeToken.get(adapterClass)).construct();
JsonSerializer<?> serializer = null;
JsonDeserializer<?> deserializer = null;
if (instance instanceof JsonSerializer) {
serializer = (JsonSerializer<?>) instance;
}
if (instance instanceof JsonDeserializer) {
deserializer = (JsonDeserializer<?>) instance;
}
// 创建TreeTypeAdapter包装器
return new TreeTypeAdapter<>(
serializer, deserializer, gson, typeToken.getType(), null);
}
throw new IllegalArgumentException(
"@JsonAdapter value must be TypeAdapter, " +
"TypeAdapterFactory, JsonSerializer or JsonDeserializer reference.");
}
}
2.3 注解优先级
@JsonAdapter注解具有较高优先级,会覆盖Gson的默认序列化策略:
- 优先于
TypeAdapterFactory工厂链 - 优先于反射序列化机制
- 仅作用于被注解的类或字段
三、TypeAdapter接口实现原理
3.1 TypeAdapter接口定义
TypeAdapter是Gson序列化的核心接口,定义了读写方法:
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;
// 创建支持null值的适配器
public TypeAdapter<T> nullSafe() {
return new TypeAdapter<T>() {
@Override
public void write(JsonWriter out, T value) throws IOException {
if (value == null) {
out.nullValue();
} else {
TypeAdapter.this.write(out, value);
}
}
@Override
public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return TypeAdapter.this.read(in);
}
};
}
}
3.2 自定义TypeAdapter示例
以日期类型为例:
public class DateTypeAdapter extends TypeAdapter<Date> {
private static final String DATE_FORMAT = "yyyy-MM-dd";
private final SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
@Override
public void write(JsonWriter out, Date value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
// 格式化日期为字符串
String dateStr = formatter.format(value);
out.value(dateStr);
}
@Override
public Date read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
String dateStr = in.nextString();
try {
// 解析字符串为日期对象
return formatter.parse(dateStr);
} catch (ParseException e) {
throw new JsonSyntaxException(e);
}
}
}
3.3 注册与使用
通过GsonBuilder注册:
Gson gson = new GsonBuilder()
.registerTypeAdapter(Date.class, new DateTypeAdapter())
.create();
四、TypeAdapterFactory工厂注入原理
4.1 工厂接口定义
TypeAdapterFactory用于动态创建TypeAdapter实例:
public interface TypeAdapterFactory {
// 创建TypeAdapter实例
<T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken);
}
4.2 自定义工厂实现
示例:为所有Enum类型创建统一适配器
public class EnumTypeAdapterFactory implements TypeAdapterFactory {
@Override
@SuppressWarnings("unchecked")
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Class<? super T> rawType = typeToken.getRawType();
// 检查是否为Enum类型
if (!rawType.isEnum()) {
return null;
}
// 创建Enum类型适配器
return (TypeAdapter<T>) new EnumTypeAdapter<>((Class<T>) rawType);
}
private static class EnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
private final Class<T> type;
private final T[] constants;
EnumTypeAdapter(Class<T> type) {
this.type = type;
this.constants = type.getEnumConstants();
}
@Override
public void write(JsonWriter out, T value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
// 写入枚举名称
out.value(value.name());
}
@Override
public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
String name = in.nextString();
// 查找枚举常量
for (T constant : constants) {
if (constant.name().equals(name)) {
return constant;
}
}
throw new JsonSyntaxException(
"Cannot deserialize enum " + type.getName() + " value: " + name);
}
}
}
4.3 工厂链执行机制
Gson按顺序遍历TypeAdapterFactory链:
public class Gson {
private final List<TypeAdapterFactory> factories;
public Gson(Builder builder) {
// 初始化工厂链
this.factories = builder.factories;
}
public <T> TypeAdapter<T> getAdapter(TypeToken<T> typeToken) {
TypeAdapter<?> cached = typeTokenCache.get(typeToken);
if (cached != null) {
return (TypeAdapter<T>) cached;
}
synchronized (typeTokenCache) {
cached = typeTokenCache.get(typeToken);
if (cached != null) {
return (TypeAdapter<T>) cached;
}
TypeAdapter<T> adapter = null;
for (TypeAdapterFactory factory : factories) {
// 依次尝试创建适配器
adapter = factory.create(this, typeToken);
if (adapter != null) {
break;
}
}
if (adapter == null) {
throw new IllegalArgumentException(
"Gson cannot serialize " + typeToken);
}
typeTokenCache.put(typeToken, adapter);
return adapter;
}
}
}
五、JsonSerializer/JsonDeserializer接口注入原理
5.1 接口定义
public interface JsonSerializer<T> {
// 序列化逻辑
JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context);
}
public interface JsonDeserializer<T> {
// 反序列化逻辑
T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException;
}
5.2 自定义实现示例
以自定义对象的序列化为例:
public class UserSerializer implements JsonSerializer<User> {
@Override
public JsonElement serialize(User user, Type typeOfSrc,
JsonSerializationContext context) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("username", user.getUsername());
// 忽略敏感字段
// jsonObject.addProperty("password", user.getPassword());
return jsonObject;
}
}
public class UserDeserializer implements JsonDeserializer<User> {
@Override
public User deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
User user = new User();
user.setUsername(jsonObject.get("username").getAsString());
// 可为密码设置默认值
// user.setPassword("default_password");
return user;
}
}
5.3 注册与使用
Gson gson = new GsonBuilder()
.registerTypeAdapter(User.class,
new TypeAdapter<User>() {
private final JsonSerializer<User> serializer =
new UserSerializer();
private final JsonDeserializer<User> deserializer =
new UserDeserializer();
@Override
public void write(JsonWriter out, User value)
throws IOException {
JsonElement jsonElement = serializer.serialize(
value, User.class, null);
new JsonTreeWriter(out).value(jsonElement);
}
@Override
public User read(JsonReader in) throws IOException {
JsonElement jsonElement = new JsonParser().parse(in);
return deserializer.deserialize(
jsonElement, User.class, null);
}
})
.create();
六、混合使用与优先级控制
6.1 多种方式结合
开发者可以混合使用不同注入方式:
- 使用
@JsonAdapter注解指定全局适配器 - 通过
TypeAdapterFactory处理特定类型家族 - 直接实现
TypeAdapter处理个别类型
6.2 优先级规则
@JsonAdapter注解 >TypeAdapterFactory> 反射序列化- 自定义
TypeAdapter> 内置类型适配器 - 后注册的
TypeAdapterFactory覆盖先注册的实现