摘要:版本版本簡介是谷歌開源的解析工具。其實幾款產品的差別都很細微,有谷歌的信仰加成,所以在這里進行一次源碼分析。至于和會在后續(xù)進行追蹤。
零 前期準備 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 Demopackage 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.>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. emptyList(), Collections. emptyList(), Collections. emptyList()); }
繼續(xù)追蹤:
//Gson.class Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingStrategy, final Map> instanceCreators, boolean serializeNulls, boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe, boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues, LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle, int timeStyle, List builderFactories, List builderHierarchyFactories, List factoriesToBeAdded) { //排除器,在序列化對象的時候會根據使用者設置的規(guī)則排除一些數據 //排除策略需要使用者自行實現 ExclusionStrategy 接口來制定 this.excluder = excluder; //fieldNamingStrategy 負責命名規(guī)則的確定(比如 大駝峰命名、小駝峰命名、下劃線命名 等) //選擇不同的 fieldNamingStrategy 會在輸出 json 字符串的時候把字段名稱轉成不同的命名形式 //此處的值可以直接選擇 FieldNamingPolicy 枚舉類中的已經存儲的策略,也可以自行實現 FieldNamingStrategy 接口 //此處默認為 FieldNamingPolicy.IDENTITY,即不改變 this.fieldNamingStrategy = fieldNamingStrategy; //instanceCreators 是一個用來存儲實現了 InstanceCreator 接口的對象的 map //每一個 InstanceCreator 的實現類用來反射獲取一種特定類型的 bean 對象 //InstanceCreator 在 Gson 中沒有實現類,使用者可以自行定制 //此處為空 map this.instanceCreators = instanceCreators; //ConstructorConstructor 用來統(tǒng)一調度 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; //是否要生成不可執(zhí)行的 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 factories = new ArrayList (); //TypeAdapters 是 TypeAdapter 和 TypeAdapterFactory 的通用工具類 //處理 JsonElement 類型對象的 TypeAdapterFactory //JsonElement 是 Gson 工具包中的一個類 factories.add(TypeAdapters.JSON_ELEMENT_FACTORY); //處理 Object 類型對象的 TypeAdapterFactory factories.add(ObjectTypeAdapter.FACTORY); //excluder 是一個省略了類型的 TypeAdapterFactory //根據官方注釋,excluder 需要先于所有使用者自定義的 TypeAdapterFactory 去執(zhí)行 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 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() //創(chuàng)建解析器對象 .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 { //在這個方法中實現自定義的命名規(guī)則 public String translateName(Field f); }
FieldNamingPolicy 是一個實現了 FieldNamingStrategy 接口的枚舉類,其中實現了多套 translateName(...) 方法可供選擇。
二 TypeAdapter 和 TypeAdapterFactory在 Gson 中封裝了不同類型的讀寫的業(yè)務組裝類是各個 TypeAdapter(適配器),這里先來關注一下其具體實現。
1 父類與接口先來看一下 TypeAdapterFactory 接口:
public interface TypeAdapterFactory { //只有一個方法,用于根據解析器和變量類型來創(chuàng)建 TypeAdapterTypeAdapter create(Gson gson, TypeToken type); }
再來看一下 TypeAdapter 抽象類:
public abstract class TypeAdapter2 StringTypeAdapter{ //寫入方法,主要的指揮 JsonWriter 進行業(yè)務處理 public abstract void write(JsonWriter out, T value) throws IOException; //讀取方法,主要是指揮 JsonReader 進行業(yè)務操作 public abstract T read(JsonReader in) throws IOException; //該抽象類中還提供了其它的方法,在此例中沒有用到,暫時忽略 }
關注一下下列這行代碼:
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 TypeAdapterSTRING = new TypeAdapter () { //此方法用于反序列化時讀取值 @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); } };
繼續(xù)追蹤 newFactory(...) 方法:
//TypeAdapters.class public static TypeAdapterFactory newFactory(final Class type, final TypeAdapter typeAdapter) { return new TypeAdapterFactory() { @SuppressWarnings("unchecked") @Override publicTypeAdapter create(Gson gson, TypeToken typeToken) { //typeToken.getRawType() 會獲取到這個 TypeToken 所需要的 return typeToken.getRawType() == type ? (TypeAdapter ) typeAdapter : null; } //常規(guī)的重新 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 publicTypeAdapter create(Gson gson, final TypeToken type) { Class super T> raw = type.getRawType(); //要確保 type 中獲取出來的 class 的類型是 Object 的子類 //如果不是的話就代表這是基本類型,基本類型的解析不應該使用該適配器 //所以返回 null if (!Object.class.isAssignableFrom(raw)) { return null; } //constructor 用于反射創(chuàng)建對象 ObjectConstructor constructor = constructorConstructor.get(type); //Adapter 是 ReflectiveTypeAdapterFactory 的靜態(tài)內部類,繼承了 TypeAdapter return new Adapter (constructor, getBoundFields(gson, type, raw)); }
來繼續(xù)追蹤一下 Adapter 的主要方法:
public static final class Adapterextends TypeAdapter { //此處 read(...) 和 write(...) 的代碼比較類似 //主要步驟是通過反射創(chuàng)建出對象,并抓取其所有的變量,逐個存入 public T read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } //調用構造器反射創(chuàng)建出對象 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 會在后續(xù)進行追蹤。
To Be Continued ...文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/72824.html
摘要:接上篇三和在進行的序列化和反序列化源碼解析之前先了解一下其主體工具類。是中用于序列化的主體。同時為了兼顧性能做了很多有意思的設計,比如獲取適配器的時候的雙緩存設計,應該是為了提高解析器的復用效率,具體有待研究。 接上篇 三 JsonReader 和 JsonWriter 在進行 json 的序列化和反序列化源碼解析之前先了解一下其主體工具類。 1 JsonReader JsonRead...
摘要:的前位數用來表示線程的數量,后面三位用來表示線程池的狀態(tài)。線程池的狀態(tài)有五種,分別是,根據單詞就能猜出大概。并且為了考慮性能問題,線程池的設計沒有使用悲觀鎖關鍵字,而是大量使用了和機制。 零 前期準備 0 FBI WARNING 文章異常啰嗦且繞彎。 1 版本 JDK 版本 : OpenJDK 11.0.1 IDE : idea 2018.3 2 ThreadPoolExecutor ...
摘要:看下圖所示,摘自網絡的創(chuàng)建流程源碼分析實例是使用建造者模式通過類進行創(chuàng)建的。創(chuàng)建了一個含有對象實例的,并返回給源碼分析添加一個調用適配器工廠,用于支持服務方法返回類型注意生產的是,那么又是什么呢可以看到源代碼如下所示,它是一個接口。 目錄介紹 1.首先回顧Retrofit簡單使用方法 2.Retrofit的創(chuàng)建流程源碼分析 2.1 Retrofit對象調用Builder()源碼解...
摘要:六修改內部類的方法這個的方法是對類型的數據進行解析,我們判斷輸入的數據類型不是類型,就直接跳過解析,核心是在方法中插入方法。每一個類每一個內部類每一個匿名內部類,都會生成一個獨立的文件,如。 一、項目地址 項目地址:github-gson-plugin 二、ReaderTools解析 /** * Created by tangfuling on 2018/10/23. */ pu...
閱讀 489·2021-09-03 00:22
閱讀 1365·2021-08-03 14:03
閱讀 2082·2021-07-25 21:37
閱讀 646·2019-08-30 13:18
閱讀 1875·2019-08-29 16:19
閱讀 2682·2019-08-29 13:22
閱讀 1293·2019-08-29 12:16
閱讀 2587·2019-08-26 12:16