Android Gson自定义序列化行为的注入方式原理(21)

98 阅读4分钟

Android Gson自定义序列化行为的注入方式原理剖析

一、自定义序列化行为注入概述

1.1 注入需求与应用场景

在Android开发中,Gson默认的序列化机制有时无法满足复杂业务需求,例如:

  • 对特殊数据类型(如日期、枚举)进行特定格式转换
  • 隐藏或修改对象中敏感字段
  • 为序列化结果添加额外元数据
  • 优化复杂对象的序列化性能

通过自定义序列化行为注入,开发者能够灵活控制对象到JSON的转换过程,增强Gson的扩展性和适应性。

1.2 核心注入方式

Gson支持以下几种自定义序列化行为的注入方式:

  1. @JsonAdapter注解:通过注解指定自定义的TypeAdapter
  2. 实现TypeAdapter接口:直接实现TypeAdapter处理特定类型
  3. TypeAdapterFactory工厂:动态创建TypeAdapter实例
  4. 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的默认序列化策略:

  1. 优先于TypeAdapterFactory工厂链
  2. 优先于反射序列化机制
  3. 仅作用于被注解的类或字段

三、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 多种方式结合

开发者可以混合使用不同注入方式:

  1. 使用@JsonAdapter注解指定全局适配器
  2. 通过TypeAdapterFactory处理特定类型家族
  3. 直接实现TypeAdapter处理个别类型

6.2 优先级规则

  1. @JsonAdapter注解 > TypeAdapterFactory > 反射序列化
  2. 自定义TypeAdapter > 内置类型适配器
  3. 后注册的TypeAdapterFactory覆盖先注册的实现