全部序列化的API都在JSON類中,方法名稱爲toJSONString,或者咱們也能夠設計本身的序列化方法,代碼以下:java
public class MyJSON { public static String toJSONString(Object object, SerializeConfig config, SerializeFilter[] filters, SerializerFeature[] features) { SerializeWriter out = new SerializeWriter(); try { // SerializeConfig能夠理解爲一個Map<Type,ObjectSerializer>, // 內部保存着類型與對應的對象序列化器之間的映射關係 if (config == null) config = SerializeConfig.getGlobalInstance(); // 核心序列化器,主要負責調用SerializeConfig根據value選擇合適的對象序列化器 // 內部還保存着輸出流對象,以及各類過濾器 JSONSerializer serializer = new JSONSerializer(out, config); // 全部特性最終會合成爲一個int值,保存在輸出流對象中 if (features != null) for (SerializerFeature feature : features) { serializer.config(feature, true); } // 如上面所說,過濾器保存在覈心序列化器中 if (filters != null && filters.length > 0) setFilter(serializer, filters); // 序列化過程的入口方法 serializer.write(object); return out.toString(); } finally { out.close(); } } private static void setFilter(JSONSerializer serializer, SerializeFilter... filters) { for (SerializeFilter filter : filters) { setFilter(serializer, filter); } } private static void setFilter(JSONSerializer serializer, SerializeFilter filter) { if (filter == null) { return; } if (filter instanceof PropertyPreFilter) { serializer.getPropertyPreFilters().add((PropertyPreFilter) filter); } if (filter instanceof NameFilter) { serializer.getNameFilters().add((NameFilter) filter); } if (filter instanceof ValueFilter) { serializer.getValueFilters().add((ValueFilter) filter); } if (filter instanceof PropertyFilter) { serializer.getPropertyFilters().add((PropertyFilter) filter); } if (filter instanceof BeforeFilter) { serializer.getBeforeFilters().add((BeforeFilter) filter); } if (filter instanceof AfterFilter) { serializer.getAfterFilters().add((AfterFilter) filter); } if (filter instanceof LabelFilter) { serializer.getLabelFilters().add((LabelFilter) filter); } } }
調用方法時須要傳入一個要序列化的目標對象object,以及三個可選參數,分別爲SerializeConfig、SerializeFilter[]、SerializerFeature[]。這三個參數之因此爲可選,是由於它們均有默認配置。spring
SerializeConfig:序列化配置,咱們能夠把它理解爲一個Map<Class,ObjectSerializer>,它的內部保存着全部被序列化對象的類型,與序列化此對象要使用的ObjectSerializer序列化器之間的映射關係。另外,若是遇到不存在的javaBean類型,它的內部還能夠自動建立JavaBeanSerializer(包括直接建立JavaBeanSerializer對象,或者經過asm框架建立ASMJavaBeanSerializer的子類對象)。sql
SerializeFilter:序列化過濾器???json
SerializerFeature:序列化器特性,主要用於控制序列化過程當中的一些行爲特性數組
序列化過程的入口其實就是serializer.write(object);方法的調用,具體執行過程以下:oracle
public final void write(Object object) { // 若是value爲null則直接輸出"null"並返回 if (object == null) { out.writeNull(); return; } // 獲取value對象的類型 Class<?> clazz = object.getClass(); // 根據Class類型,從SerializeConfig中選擇合適的ObjectSerializer ObjectSerializer writer = getObjectWriter(clazz); try { // 調用ObjectSerializer序列化這個value // 由於輸入的初始value對象沒有與之對應的字段名稱, // 所以第三(字段名稱)和第四(字段類型)兩個參數爲null writer.write(this, object, null, null, 0); } catch (IOException e) { throw new JSONException(e.getMessage(), e); } }
這就是爲何我說JSONSerializer只負責調用SerializeConfig選擇合適的ObjectSerializer進行序列化的緣由。框架
所以,咱們須要關注的重點有三個:ui
fastjson內部有多少種對象序列化器(即ObjectSerializer有多少個實現類)?this
每種對象序列化器是如何工做的?atom
SerializeConfig中有多少種類型與對象序列化器之間的映射關係
ObjectSerializer接口類圖以下:(點擊可查看放大後的清晰圖片)
整個體系共計61個實現類,以及一個子接口(AutowiredObjectSerializer)
具體每種對象序列化器如何工做,我會單開專題講解,
在SerializeConfig的構造方法中,會添加許多默認支持的映射關係,每一個新建立的SerializeConfig對象,都會支持這些類型的序列化。
put(Boolean.class, BooleanCodec.instance); put(Character.class, CharacterCodec.instance); put(Byte.class, IntegerCodec.instance); put(Short.class, IntegerCodec.instance); put(Integer.class, IntegerCodec.instance); put(Long.class, LongCodec.instance); put(Float.class, FloatCodec.instance); put(Double.class, DoubleSerializer.instance); put(BigDecimal.class, BigDecimalCodec.instance); put(BigInteger.class, BigIntegerCodec.instance); put(String.class, StringCodec.instance); put(byte[].class, ByteArraySerializer.instance); put(short[].class, ShortArraySerializer.instance); put(int[].class, IntArraySerializer.instance); put(long[].class, LongArraySerializer.instance); put(float[].class, FloatArraySerializer.instance); put(double[].class, DoubleArraySerializer.instance); put(boolean[].class, BooleanArraySerializer.instance); put(char[].class, CharArraySerializer.instance); put(Object[].class, ObjectArraySerializer.instance); put(Class.class, ClassSerializer.instance); put(SimpleDateFormat.class, DateFormatSerializer.instance); put(Locale.class, LocaleCodec.instance); put(Currency.class, CurrencyCodec.instance); put(TimeZone.class, TimeZoneCodec.instance); put(UUID.class, UUIDCodec.instance); put(InetAddress.class, InetAddressCodec.instance); put(Inet4Address.class, InetAddressCodec.instance); put(Inet6Address.class, InetAddressCodec.instance); put(InetSocketAddress.class, InetSocketAddressCodec.instance); put(File.class, FileCodec.instance); put(URI.class, URICodec.instance); put(URL.class, URLCodec.instance); put(Appendable.class, AppendableSerializer.instance); put(StringBuffer.class, AppendableSerializer.instance); put(StringBuilder.class, AppendableSerializer.instance); put(Pattern.class, PatternCodec.instance); put(Charset.class, CharsetCodec.instance); // atomic put(AtomicBoolean.class, AtomicBooleanSerializer.instance); put(AtomicInteger.class, AtomicIntegerSerializer.instance); put(AtomicLong.class, AtomicLongSerializer.instance); put(AtomicReference.class, ReferenceCodec.instance); put(AtomicIntegerArray.class, AtomicIntegerArrayCodec.instance); put(AtomicLongArray.class, AtomicLongArrayCodec.instance); put(WeakReference.class, ReferenceCodec.instance); put(SoftReference.class, ReferenceCodec.instance); // awt if (!awtError) { try { put(Class.forName("java.awt.Color"), ColorCodec.instance); put(Class.forName("java.awt.Font"), FontCodec.instance); put(Class.forName("java.awt.Point"), PointCodec.instance); put(Class.forName("java.awt.Rectangle"), RectangleCodec.instance); } catch (Throwable e) { awtError = true; // skip } } // jdk8 if (!jdk8Error) { try { put(Class.forName("java.time.LocalDateTime"), Jdk8DateCodec.instance); put(Class.forName("java.time.LocalDate"), Jdk8DateCodec.instance); put(Class.forName("java.time.LocalTime"), Jdk8DateCodec.instance); put(Class.forName("java.time.ZonedDateTime"), Jdk8DateCodec.instance); put(Class.forName("java.time.OffsetDateTime"), Jdk8DateCodec.instance); put(Class.forName("java.time.OffsetTime"), Jdk8DateCodec.instance); put(Class.forName("java.time.ZoneOffset"), Jdk8DateCodec.instance); put(Class.forName("java.time.ZoneRegion"), Jdk8DateCodec.instance); put(Class.forName("java.time.Period"), Jdk8DateCodec.instance); put(Class.forName("java.time.Duration"), Jdk8DateCodec.instance); put(Class.forName("java.time.Instant"), Jdk8DateCodec.instance); } catch (Throwable e) { // skip jdk8Error = true; } } if (!oracleJdbcError) { try { put(Class.forName("oracle.sql.DATE"), DateSerializer.instance); put(Class.forName("oracle.sql.TIMESTAMP"), DateSerializer.instance); } catch (Throwable e) { // skip oracleJdbcError = true; } }
所以,fastjson預約義的ObjectSerializer可識別的類型包括:
基本類型包裝類:Boolean、Character、Byte、Short、Integer、Long、Float、Double
高精度數:BigDecimal、BigInteger
String
基本類型的數組:boolean[]、char[]、byte[]、short[]、int[]、long[]、float[]、double[]
Object[]、Class、SimpleDateFormat、Locale、Currency、TimeZone、UUID、InetAddress、Inet4Address、Inet6Address、InetSocketAddress、File、URI、URL、Appendable、StringBuffer、StringBuilder、Pattern、Charset
原子性對象:AtomicBoolean、AtomicInteger、AtomicLong、AtomicReference、AtomicIntegerArray、AtomicLongArray
引用對象:WeakReference、SoftReference
awt相關類型:java.awt.Color、java.awt.Font、java.awt.Point、java.awt.Rectangle
jdk8特有類型(java.time包中):LocalDateTime、LocalDate、LocalTime、ZonedDateTime、OffsetDateTime、OffsetTime、ZoneOffset、ZoneRegion、Period、Duration、Instant
oracle特有類型(oracle.sql包中):DATE、TIMESTAMP
另外,fastjson還能夠識別一些類型,不光能夠識別這些類型,還能夠識別這些類型的全部子類。因爲不肯定這些類具體有多少子類,不可能提早把這些子類的Class對象都添加到map中。所以採起的是,只要某一類型是這些可識別類型或其子類,則即時添加到SerializeConfig中。舉個例子:fastjson能夠識別全部Map接口的實現類,但不可能提早知道咱們自定義的Map接口實現類(如:MyMap.class),因此當遇到這個自定義實現類的時候,才把映射關係添加到map中。
這些可識別的類型包括:
Map接口及其實現類
List接口及其實現類
Collection接口及其實現類
Date及其子類
JSONAware及其實現類
JSONSerializable接口及其實現類
JSONStreamAware接口及其實現類
枚舉類型及其子類
數組類型
Throwable及其子類
TimeZone及其子類
Appendable及其子類
Charset及其子類
Enumeration及其子類
Calendar及其子類
Clob及其子類
除了以上提到的這些全部類型外,其餘類型所有爲不可識別類型。對於不可識別的類型,所有使用JavaBeanSerializer或者ASMJavaBeanSerializer的子類(asm動態生成)進行序列化。
SerializeConfig選擇序列化器的邏輯以下:
public ObjectSerializer getObjectWriter(Class<?> clazz) { // 從已存在的映射關係中,查找序列化器 ObjectSerializer writer = get(clazz); // 若是沒有找到 if (writer == null) { try { // 獲取當前線程使用的類加載器 final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // 使用類加載器嘗試加載"META-INF/services/com.alibaba.fastjson.serializer.AutowiredObjectSerializer" // 這個文件中保存的全部類(一行一個類的全限定名),並調用無參構造建立對象 for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) { // 若是該類沒有實現AutowiredObjectSerializer則忽略 if (!(o instanceof AutowiredObjectSerializer)) { continue; } AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o; // 把這個序列化器能夠處理的類型集合添加到map中 for (Type forType : autowired.getAutowiredFor()) { put(forType, autowired); } } } catch (ClassCastException ex) { // skip } // 再次嘗試獲取對象序列化器 writer = get(clazz); } // 若是仍是沒有找到 if (writer == null) { // 獲取加載JSON類的類加載器 final ClassLoader classLoader = JSON.class.getClassLoader(); // 若是當前線程使用的不是這個類加載器,則再次重複上面的步驟 if (classLoader != Thread.currentThread().getContextClassLoader()) { try { for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) { if (!(o instanceof AutowiredObjectSerializer)) { continue; } AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o; for (Type forType : autowired.getAutowiredFor()) { put(forType, autowired); } } } catch (ClassCastException ex) { // skip } // 再次嘗試獲取 writer = get(clazz); } } // 若是仍找不到,則進行下面的邏輯處理 if (writer == null) { if (Map.class.isAssignableFrom(clazz)) { put(clazz, MapSerializer.instance); } else if (List.class.isAssignableFrom(clazz)) { put(clazz, ListSerializer.instance); } else if (Collection.class.isAssignableFrom(clazz)) { put(clazz, CollectionSerializer.instance); } else if (Date.class.isAssignableFrom(clazz)) { put(clazz, DateSerializer.instance); } else if (JSONAware.class.isAssignableFrom(clazz)) { put(clazz, JSONAwareSerializer.instance); } else if (JSONSerializable.class.isAssignableFrom(clazz)) { put(clazz, JSONSerializableSerializer.instance); } else if (JSONStreamAware.class.isAssignableFrom(clazz)) { put(clazz, JSONStreamAwareSerializer.instance); } else if (clazz.isEnum() || (clazz.getSuperclass() != null && clazz.getSuperclass().isEnum())) { put(clazz, EnumSerializer.instance); } else if (clazz.isArray()) { Class<?> componentType = clazz.getComponentType(); ObjectSerializer compObjectSerializer = getObjectWriter(componentType); put(clazz, new ArraySerializer(componentType, compObjectSerializer)); } else if (Throwable.class.isAssignableFrom(clazz)) { put(clazz, new ExceptionSerializer(clazz)); } else if (TimeZone.class.isAssignableFrom(clazz)) { put(clazz, TimeZoneCodec.instance); } else if (Appendable.class.isAssignableFrom(clazz)) { put(clazz, AppendableSerializer.instance); } else if (Charset.class.isAssignableFrom(clazz)) { put(clazz, CharsetCodec.instance); } else if (Enumeration.class.isAssignableFrom(clazz)) { put(clazz, EnumerationSeriliazer.instance); } else if (Calendar.class.isAssignableFrom(clazz)) { put(clazz, CalendarCodec.instance); } else if (Clob.class.isAssignableFrom(clazz)) { put(clazz, ClobSeriliazer.instance); } else { boolean isCglibProxy = false; boolean isJavassistProxy = false; for (Class<?> item : clazz.getInterfaces()) { if (item.getName().equals("net.sf.cglib.proxy.Factory") || item.getName().equals("org.springframework.cglib.proxy.Factory")) { isCglibProxy = true; break; } else if (item.getName().equals("javassist.util.proxy.ProxyObject")) { isJavassistProxy = true; break; } } if (isCglibProxy || isJavassistProxy) { Class<?> superClazz = clazz.getSuperclass(); ObjectSerializer superWriter = getObjectWriter(superClazz); put(clazz, superWriter); return superWriter; } if (Proxy.isProxyClass(clazz)) { put(clazz, createJavaBeanSerializer(clazz)); } else { put(clazz, createJavaBeanSerializer(clazz)); } } writer = get(clazz); } return writer; }