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);

    }
    ……
}

三、反序列化

反序列化流程和序列化流程差不多,在这我就不过多介绍,感兴趣的同学可以继续查看源码分析,培养阅读源码的兴趣。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值