fastJson序列化和反序列化流程

fastJson序列化和反序列化流程

一、核心源碼

1、SerializeWriter

該類主要用於序列化,有以下成員變量

public final class SerializeWriter extends Writer {
  /**
     * 儲存序列化結果的字段
     */
    protected char buf[];

    /**
     * 寫入緩存的長度
     */
    protected int count;

	/**
     * 該對象用於close時將buf綁定到線程上,避免下次重複new出
     */
    private final static ThreadLocal<SoftReference<char[]>> bufLocal = new ThreadLocal<SoftReference<char[]>>();
 
 	/**
     * 序列化的一些特性配置
     */
    private int features;

	/**
     * 包裝對象,支持對Writer類型包含數據的序列化
     */
    private final Writer writer;
    
    //傳入Writer對象
    public SerializeWriter(Writer writer){
        this.writer = writer;
        //默認序列化屬性
        this.features = JSON.DEFAULT_GENERATE_FEATURE;
		//獲取線程緩存buf對象
        SoftReference<char[]> ref = bufLocal.get();
	  //獲取到賦值給當前buf並清空,防止重複new出。
	  //由於count在關閉的時候已經等於0,所以即使buf裏有數據,也不會影響當次結果
        if (ref != null) {
            buf = ref.get();
            bufLocal.set(null);
        }

        if (buf == null) {
            buf = new char[1024];
        }
    }
 }

存在buf的緩存對象,自然需要具體的寫入方法。下圖列出了主要的寫入方法

Sample

類的方法結構圖

接下來我們來看默認的配置特性
JSON.DEFAULT_GENERATE_FEATURE


public abstract class JSON implements JSONStreamAware, JSONAware {

    public static int    DEFAULT_GENERATE_FEATURE;

    static {
        int features = 0;
        //輸出key時使用雙引號
        features |= SerializerFeature.QuoteFieldNames.getMask();
        //跳過Transient註解的字段
        features |= SerializerFeature.SkipTransientField.getMask();
        //將Enum枚舉轉換爲toString()字符串
        features |= SerializerFeature.WriteEnumUsingToString.getMask();
        //按字段名稱排序後輸出
        features |= SerializerFeature.SortField.getMask();
        // features |=
        // com.alibaba.fastjson.serializer.SerializerFeature.WriteSlashAsSpecial.getMask();
        DEFAULT_GENERATE_FEATURE = features;
    }
}

二、序列化

1.序列化過程

我們從調用方法toJSONString開始,會調用

public static final String toJSONString(Object object, SerializerFeature... features) {
		//詳細寫數據的類,存儲序列化過程的數據,最後通過 out.toString()轉化爲json字符串
        SerializeWriter out = new SerializeWriter();

        try {
        	//Json序列化解析對象的類,解析過程中向out寫入數據
            JSONSerializer serializer = new JSONSerializer(out);
            //向解析器添加序列化屬性
            for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) {
                serializer.config(feature, true);
            }
			//解析傳入的對象,保存在out中
            serializer.write(object);
			//將解析的結果轉成String輸出
            return out.toString();
        } finally {
            out.close();
        }
    }

接下里我們來看JSONSerializer的write方法

public class JSONSerializer {
	……
	public final void write(Object object) {
	//如果空對象,直接寫入null字符串
        if (object == null) {
            out.writeNull();
            return;
        }
	  //獲取到類,通過getObjectWriter(clazz)找到對應的解析器
        Class<?> clazz = object.getClass();
        ObjectSerializer writer = getObjectWriter(clazz);

        try {
        	//對應序列化器執行序列化寫操作
            writer.write(this, object, null, null);
        } catch (IOException e) {
            throw new JSONException(e.getMessage(), e);
        }
    }
    ……
}

那我們來看看怎麼獲取對應序列化器的

public ObjectSerializer getObjectWriter(Class<?> clazz) {
	  //先從SerializeConfig配置中獲取默認基礎類型的代碼序列化器
        ObjectSerializer writer = config.get(clazz);
        //如果未獲取到,再解析對象類型,並加入配置列表當中,例如
        if (writer == null) {
            if (Map.class.isAssignableFrom(clazz)) {
            	//Map類型
                config.put(clazz, MapSerializer.instance);
            } else if (List.class.isAssignableFrom(clazz)) {
            	//List類型
                config.put(clazz, ListSerializer.instance);
            } else if (Collection.class.isAssignableFrom(clazz)) {
				//Collection類型
                config.put(clazz, CollectionSerializer.instance);
            } else if (Date.class.isAssignableFrom(clazz)) {
            	//Date日期類型
                config.put(clazz, DateSerializer.instance);
            } else if (JSONAware.class.isAssignableFrom(clazz)) {
            	//JSONAware日期類型
                config.put(clazz, JSONAwareSerializer.instance);
            } else if (JSONSerializable.class.isAssignableFrom(clazz)) {
				//JSONSerializable日期類型
                config.put(clazz, JSONSerializableSerializer.instance);
            } else if (JSONStreamAware.class.isAssignableFrom(clazz)) {
            	//JSONStreamAware類型
                config.put(clazz, JSONStreamAwareSerializer.instance);
            } else if (clazz.isEnum() || (clazz.getSuperclass() != null && clazz.getSuperclass().isEnum())) {
            	//枚舉類型的類 
                config.put(clazz, EnumSerializer.instance);
            } else if (clazz.isArray()) {
            	//數組類型
                Class<?> componentType = clazz.getComponentType();
                ObjectSerializer compObjectSerializer = getObjectWriter(componentType);
                config.put(clazz, new ArraySerializer(componentType, compObjectSerializer));
            } else if (Throwable.class.isAssignableFrom(clazz)) {
            	//異常類型
                config.put(clazz, new ExceptionSerializer(clazz));
            } else if (TimeZone.class.isAssignableFrom(clazz)) {
            	//市區類型
                config.put(clazz, TimeZoneCodec.instance);
            } else if (Charset.class.isAssignableFrom(clazz)) {
            	//字符編碼類型
                config.put(clazz, CharsetCodec.instance);
            } else if (Enumeration.class.isAssignableFrom(clazz)) {
            	//實現了枚舉接口的類
                config.put(clazz, EnumerationSeriliazer.instance);
            } else if (Calendar.class.isAssignableFrom(clazz)) {
            	//日曆類型
                config.put(clazz, CalendarCodec.instance);
            } else {
                boolean isCglibProxy = false;
                boolean isJavassistProxy = false;
                //判斷是否是CGLIB或javassist生成的代理類
                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;
                    }
                }
				//如果是CGLIB或javassist生成的代理類,就放父類的序列化器
                if (isCglibProxy || isJavassistProxy) {
                    Class<?> superClazz = clazz.getSuperclass();

                    ObjectSerializer superWriter = getObjectWriter(superClazz);
                    config.put(clazz, superWriter);
                    return superWriter;
                }
				//不管是不是動態代理類型,都是用JavaBean序列化器
                if (Proxy.isProxyClass(clazz)) {
                    config.put(clazz, config.createJavaBeanSerializer(clazz));
                } else {
                    config.put(clazz, config.createJavaBeanSerializer(clazz));
                }
            }
			//上面向config中添加了類對應的序列化器,現在獲取Writer返回
            writer = config.get(clazz);
        }
        return writer;
    }

回過來看看第一行的默認配置的基礎解析器


public class SerializeConfig extends IdentityHashMap<Type, ObjectSerializer> {
	……
    public SerializeConfig(int tableSize){
        super(tableSize);

        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(URI.class, URICodec.instance);
        put(URL.class, URLCodec.instance);
        put(Pattern.class, PatternCodec.instance);
        put(Charset.class, CharsetCodec.instance);

    }
    ……
}

三、反序列化

反序列化流程和序列化流程差不多,在這我就不過多介紹,感興趣的同學可以繼續查看源碼分析,培養閱讀源碼的興趣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章