结论
- parse(jsonStr) :自动调用构造方法+Json字符串指定属性的setter()+特殊的getter()
- parseObject(jsonStr) :自动调用构造方法+Json字符串指定属性的setter()+所有getter() 。包括不存在属性和私有属性的getter()
- parseObject(jsonStr,Object.class) :自动调用构造方法+Json字符串指定属性的setter()+特殊的getter()
关键分析
一、序列化数据中类的获取方式
fastjson在调用toJSONString方法时如果指定SerializerFeature.WriteClassName参数时会在序列化时额外写入 Java 对象所属的类名(@type 属性),如果不指定则序列化数据中不会包含类名。

如果指定参数,那么在调用parseObject方法进行反序列化过程中就会识别@type头来获取对象的所属类。
先分析一下类的获取方式
通过断点的跟踪可以判断@type头的识别在com.alibaba.fastjson.parser.JSONLexerBase#scanSymbol(com.alibaba.fastjson.parser.SymbolTable, char)方法中进行

跟进


代码会逐字符的读取直到遇到结束的引号,将读取的结果赋值给key
整个调用栈如下:

二、parseObject(String text)反序列化过程中获取getter/setter方法
编写示例代码开始调试
package org.atoposx;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.atoposx.model.Evil;
public class FastJsonTest {
public static void main(String[] args) {
Evil evil = new Evil("evil test");
System.out.println("-------------------------------------");
/* String jsonString1 = JSON.toJSONString(evil, SerializerFeature.WriteClassName);
System.out.println(jsonString1);
String jsonString2 = JSON.toJSONString(evil);
System.out.println(jsonString2);*/
String jsonString = "{\"@type\":\"org.atoposx.model.Evil\",\"cmd\":\"evil test\"}";
System.out.println("-------------------------------------");
// JSON.parseObject(jsonString, Evil.class);
System.out.println("-------------------------------------");
ParserConfig.getGlobalInstance().setAsmEnable(false);
JSON.parseObject(jsonString);
System.out.println("-------------------------------------");
// JSON.parse(jsonString);
}
}
步入parseObject(String text)方法


步入com.alibaba.fastjson.JSON#parse(java.lang.String)方法

步入com.alibaba.fastjson.parser.DefaultJSONParser#parse()方法

步入com.alibaba.fastjson.parser.DefaultJSONParser#parse(java.lang.Object)方法

此处对lexer token做了一个判断,作用是通过不同的token类型调用不同的解析逻辑。
token类型有以下几种
- SET/TREE_SET: 特殊集合类型
- LBRACKET: JSON数组开始标记 [
- LBRACE: JSON对象开始标记 {
- LITERAL_INT: 整数字面量
- LITERAL_FLOAT: 浮点数字面量
- LITERAL_STRING: 字符串字面量
- NULL/UNDEFINED: 空值
- TRUE/FALSE: 布尔值
- NEW: 构造函数调用(如Date对象)
- EOF: 文件结束
- ERROR: 错误标记
由于传入的是json格式的字符串,所以这里识别出的token就是LBRACE

步入1327行com.alibaba.fastjson.parser.DefaultJSONParser#parseObject(java.util.Map, java.lang.Object)方法

往下走就来到了一中的识别@type头,获取类的过程,此处不再赘述
步入第367行com.alibaba.fastjson.parser.ParserConfig#getDeserializer(java.lang.reflect.Type)方法

在该方法中获取不到默认的反序列化器就会步入312行com.alibaba.fastjson.parser.ParserConfig#getDeserializer(java.lang.Class<?>, java.lang.reflect.Type)方法


往下走到第362行会经过一个黑名单判断

该过程是防止AutoType反序列化的关键步骤,不允许黑名单中的类进行反序列化,如果匹配到直接抛出异常
往下走

371行和386行的会对jdk8和java.awt.开头的一些类做特殊处理,此处不进行分析
步入第461行com.alibaba.fastjson.parser.ParserConfig#createJavaBeanDeserializer

该方法用于创建一个javabean类型的反序列化器
方法开始会对是否开启asm加速做一个判断

启用asm会提高性能,直接生成字节码,避免反射调用,所以不会走进invoke方法,不方便理解整个调用过程,所以在测试代码中禁用了asm加速。
步入586行com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer方法

步入关键方法39行com.alibaba.fastjson.util.JavaBeanInfo#build

前面部分在获取一些类的基本信息,比如fields、方法等。一直跟进到328行


遍历method获取setter方法需要满足5个条件:
- 方法名长度>4
- 非静态方法
- 返回类型是void或者当前类
- 传入参数个数必须是1
- 方法开头是set
后续代码对方法名进行处理,提取其中的属性值

最后将setter方法的相关信息储存到fieldList数组中

获取完setter之后,从490行开始获取getter方法

getter方法需要满足以下几个条件:
- 方法名称长度≥4
- 非静态方法
- 方法名称开头是get
- 传入参数个数是0
- 方法继承了Collection||Map||AtomicBoolean||AtomicInteger||AtomicLong
三、parseObject(String text)反序列化过程中自动调用getter/setter方法
setter的调用
在二中获取完setter方法后,一路return,退出com.alibaba.fastjson.parser.ParserConfig#getDeserializer(java.lang.reflect.Type)方法。
步入368行com.alibaba.fastjson.parser.deserializer.ObjectDeserializer#deserialze方法

步入com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer#deserialze(com.alibaba.fastjson.parser.DefaultJSONParser, java.lang.reflect.Type, java.lang.Object, java.lang.Object, int)方法

这里可以成功步入deserialze方法是因为一开始设置了关闭asm加速,不然程序直接从内存中进行调用,无法通过断点调试看到invoke过程。
一路步过,一直到593行
步入com.alibaba.fastjson.parser.deserializer.FieldDeserializer#setValue(java.lang.Object, java.lang.Object)


一直到96行可以看到调用了invoke方法

至此调用了setter方法
getter方法调用
一路步过,回到com.alibaba.fastjson.JSON#parseObject(java.lang.String)方法

步入com.alibaba.fastjson.JSON#toJSON(java.lang.Object)方法


872行获取类名
896行为获取的类创建序列化器,比如为Map类创建MapSerializer序列化器,为List类创建ListSerializer序列化器等,如果都没有匹配就会为JavaBean类型创建 JavaBeanSerializer序列化器。此处的evil类是标准javabean就会进入897行的if语句

之后步入关键方法902行com.alibaba.fastjson.serializer.JavaBeanSerializer#getFieldValuesMap,该方法会获取javabean对象中的字段->字段值,会调用对象的所有getter方法

sortedGetters会将所有getter方法缓存成FieldSerializer数组,循环获取字段和字段值。
439行通过com.alibaba.fastjson.serializer.FieldSerializer#getPropertyValue方法,反射调用对象的所有getter方法


整个过程调用栈如下
