Gson 2.8.5源碼解析(一)

序列化

將java對象,轉換爲Json格式的字符串

Gson gson = new Gson();
String json = gson.toJson(book);
  • 創建StringWriter對象,再將其包裝爲JsonWriter對象
  • 根據TypeToken得到TypeAdapter,回調typeAdapter.write(jsonWriter, src)
  • 最終返回的就是這個stringWriter.toString()
public String toJson(Object src) {
    return toJson(src, src.getClass());
  }

//構建StringWriter對象,並最終返回序列化之後的對象
 public String toJson(Object src, Type typeOfSrc) {
    StringWriter writer = new StringWriter(); //構建StringWriter對象
    toJson(src, typeOfSrc, writer);
    return writer.toString(); //最終返回序列化之後的對象
  }

//StringWriter包裝爲JsonWriter對象
public void toJson(Object src, Type typeOfSrc, Appendable writer) throws JsonIOException {
     JsonWriter jsonWriter = newJsonWriter(Streams.writerForAppendable(writer)); 
     toJson(src, typeOfSrc, jsonWriter);
  }

//得到一個TypeAdapter類型的對象,進行傳入jsonWriter,和對象src,寫成字節流
public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {
    TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));
    ((TypeAdapter<Object>) adapter).write(writer, src);
  }

反序列化

將json字符串轉換爲java對象

Gson gson = new Gson();
Book book = gson.fromJson(jsonStr, Book.class);
  • 構建StringReader對象,幷包裝爲JsonReader對象
  • 得到typeToken對應的typeAdapter對象
  • typeAdapter.read(jsonReader) 返回一個java對象

ReflectiveTypeAdapterFactory中的Adapter進行read操作,會構建一個新對象,並將json字符串中的value寫入對象T中。

public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException {
    Object object = fromJson(json, (Type) classOfT);
    return Primitives.wrap(classOfT).cast(object); //將object對象強轉爲T對象
  }

public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
    StringReader reader = new StringReader(json); //構建StringReader對象
    T target = (T) fromJson(reader, typeOfT);
    return target;
  }

public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
    JsonReader jsonReader = newJsonReader(json); //StringReader對象包裝爲JsonReader對象
    T object = (T) fromJson(jsonReader, typeOfT);
    return object;
  }

public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
      TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
      TypeAdapter<T> typeAdapter = getAdapter(typeToken);
      T object = typeAdapter.read(reader);
      return object;
  }

TypeAdapter的獲取

  • 做了緩存處理(不太明白calls是個threadLocal對象)
  • 遍歷,直到遇到符合規則的factory,並生成TypeAdapter對象,並放入緩存中
  • FutherTypeAdapter代理類,提供統一接口和處理

private final ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>> calls
      = new ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>>(); //每個線程保存一個Map對象

  private final Map<TypeToken<?>, TypeAdapter<?>> typeTokenCache 
  		= new ConcurrentHashMap<TypeToken<?>, TypeAdapter<?>>(); //存儲着TypeToken和typeAdapter的對應關係

 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;
    }
    //獲取當前線程的Map對象(存儲着TypeToken和FutureTypeAdapter的對應關係)
    Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get();
    boolean requiresThreadLocalCleanup = false;
    //如果當前線程沒有存儲過map對象,則新建,並放入calls中
    if (threadCalls == null) {
      threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();
      calls.set(threadCalls);
      requiresThreadLocalCleanup = true;
    }

   //從threadCalls這個map對象中取出TypeToken所對應的FutureTypeAdapter對象,如果存在,則直接返回
    FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type);
    if (ongoingCall != null) {
      return ongoingCall;
    }

    try {
      FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();
      threadCalls.put(type, call);
      //創建FutureTypeAdapter對象,並存入threadCalls中,保存TypeToken和FutureTypeAdapter的對應關係
      for (TypeAdapterFactory factory : factories) {
        TypeAdapter<T> candidate = factory.create(this, type);
        if (candidate != null) {
         //遍歷,直到遇到符合規則的factory,並生成TypeAdapter對象。
          call.setDelegate(candidate); //設置代理對象,也就是說是由candidate對數據進行真正的處理
          typeTokenCache.put(type, candidate); //放入緩存中
          return candidate;
        }
      }
      throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type);
    } finally {
    //這裏大概是緩存裏有了,就沒必要存儲了吧
      threadCalls.remove(type);
      if (requiresThreadLocalCleanup) {
        calls.remove();
      }
    }
  }

//FutureTypeAdapter繼承自TypeAdpter,僅僅是代理模式,抽象出來,統一管理
 static class FutureTypeAdapter<T> extends TypeAdapter<T> {
    private TypeAdapter<T> delegate;

    public void setDelegate(TypeAdapter<T> typeAdapter) {
      if (delegate != null) {
        throw new AssertionError();
      }
      delegate = typeAdapter;
    }

    @Override public T read(JsonReader in) throws IOException {
      if (delegate == null) {
        throw new IllegalStateException();
      }
      return delegate.read(in);
    }

    @Override public void write(JsonWriter out, T value) throws IOException {
      if (delegate == null) {
        throw new IllegalStateException();
      }
      delegate.write(out, value);
    }
  }

Factory的來源

  • 默認有41個factory,很多元數據的處理,String/Integer/Boolean等
  • 對於我們這個案例來說,用的是ReflectiveTypeAdapterFactory
    在這裏插入圖片描述

ReflectiveTypeAdapterFactory

  • 工廠類,返回一個靜態內部類Adapter,通過反射的方式讀取寫入相應的值
public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory {

@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)); //getBoundFileds通過反射拿到所有的filed
  }

 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;
    }
	
	//反序列化,JsonReader讀取字節流,返回一個T類型的對象
    @Override public T read(JsonReader in) throws IOException {
      T instance = constructor.construct();
        in.beginObject();
        while (in.hasNext()) {
          String name = in.nextName();
          BoundField field = boundFields.get(name);
          if (field == null || !field.deserialized) {
            in.skipValue(); //
          } else {
            field.read(in, instance);
          }
        }
      in.endObject();
      return instance;
    }

	//序列化,T對象,通過JsonWriter進行寫操作,最終writer.toString返回一個json類型的字符串
    @Override public void write(JsonWriter out, T value) throws IOException {
      out.beginObject();
        for (BoundField boundField : boundFields.values()) {
          if (boundField.writeField(value)) {
            out.name(boundField.name); //寫入key值
            boundField.write(out, value); //寫入value值
          }
        }
      out.endObject();
    }
  }
}

序列化、反序列化總結

  • 序列化:將java對象轉換爲json類型的字符串
  • 反序列化:將json字符串轉換爲Java對象
  • 如果沒有自定義TokenAdapter、JsonSerializer、JsonDeserializer,且爲自定義對象類型,大都是通過ReflectiveTypeAdapterFactory中的Adapter進行write操作。

序列化:

  1. 構建StringWriter對象,包裝爲JsonWriter對象
  2. 得到typeToken對應的typeAdapter對象
  3. 回調typeAdapter.write(jsonWriter, T)
  4. 返回jsonWriter.toString()

反序列化:

  1. 構建StringReader,幷包裝爲JsonReader對象
  2. 得到typeToken對應的typeAdapter對象
  3. 回調typeAdapter.read(jsonReader),返回java對象T
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章