从 JSON 字符串到 Java 对象:Fastjson 1.2.83 全程解析|得物技术
三、项目结构
com.alibaba.fastjson/
├── JSON.java # 核心入口类
├── annotation/ # 注解定义
├── asm/ # ASM字节码精简库
├── parser/ # 解析器模块
│ ├── DefaultJSONParser.java # 默认JSON解析器
│ ├── JSONLexer.java # 词法分析器接口
│ ├── JSONScanner.java # 词法分析器实现
│ └── deserializer/ # 反序列化器
├── serializer/ # 序列化器模块
│ ├── JSONSerializer.java # JSON序列化器
│ ├── SerializeConfig.java # 序列化配置
│ └── ObjectSerializer.java # 对象序列化器接口
├── spi/ # SPI扩展机制
├── support/ # 框架支持
└── util/ # 工具类
3.1 项目结构说明
主要可以划分为以下几个核心模块(包):
com.alibaba.fastjson (核心 API 与数据结构)
- 关键类 :
- JSON.java: 整个库的门面(Facade),提供了最常用、最便捷的静态方法,如 toJSONString () (序列化), parseObject () (反序列化为对象), parseArray () (反序列化为数组)。通常它是用户最先接触到的类。
- JSONObject.java: 继承自 java.util.HashMap,用于表示 JSON 对象结构( {key: value} )。
- JSONArray.java: 继承自 java.util.ArrayList,用于表示 JSON 数组结构 ([value1, value2] )。
com.alibaba.fastjson.serializer (序列化模块)
此模块负责将 Java 对象转换为 JSON 格式的字符串
- 关键类 :
- JSONSerializer.java: 序列化的核心调度器。它维护了序列化的上下文信息,如对象引用、循环依赖检测、特性( SerializerFeature )开关等,并驱动整个序列化过程。
- SerializeWriter.java: 一个高度优化的 Writer 实现,专门用于生成 JSON 字符串。它内部使用 char [] 数组来拼接字符串,避免了 String 的不可变性带来的性能损耗,是 Fastjson 高性能写入的关键。
- JavaBeanSerializer.java: 默认的 JavaBean 序列化器。在未启用 ASM 优化时,它通过反射获取对象的属性( getter 方法)并将其序列化。
- ASMSerializerFactory.java: 性能优化的核心 。它使用 ASM 字节码技术在运行时动态生成序列化器类,这些类直接调用 getter 方法并操作 SerializeWriter,避免了反射的性能开销。
- ObjectSerializer.java: 序列化器接口。用户可以通过实现此接口来为特定类型提供自定义的序列化逻辑。
- SerializeConfig.java: 序列化配置类。它维护了 Java 类型到 ObjectSerializer 的缓存。 SerializeConfig.getGlobalInstance () 提供了全局唯一的配置实例。
- SerializerFeature.java: 序列化特性枚举。定义了各种序列化行为的开关,例如 WriteMapNullValue (输出 null 值的字段)、 DisableCircularReferenceDetect (禁用循环引用检测) 等。
com.alibaba.fastjson.parser (反序列化模块)
此模块负责将 JSON 格式的字符串解析为 Java 对象。
- 关键类 :
- DefaultJSONParser.java: 反序列化的核心调度器。它负责解析 JSON 字符串的整个过程,管理 JSONLexer 进行词法分析,并根据 Token (如 { ,} , [ , ] , string , number 等) 构建 Java 对象。
- JSONLexer.java/ JSONLexerBase.java: JSON 词法分析器。它负责扫描输入的 JSON 字符串,将其切割成一个个有意义的 Token ,供 DefaultJSONParser 使用。
- JavaBeanDeserializer.java: 默认的 JavaBean 反序列化器。在未启用 ASM 优化时,它通过反射创建对象实例并设置其属性值。
- ASMDeserializerFactory.java: 与序列化类似,它动态生成反序列化器字节码,直接调用 setter 方法或直接对字段赋值,避免了反射。
- ObjectDeserializer.java: 反序列化器接口。用户可以实现此接口来自定义特定类型的反序列化逻辑。
- ParserConfig.java: 反序列化配置类。维护了 Java 类型到 ObjectDeserializer 缓存,并负责管理 ASM 生成的类的加载。
- Feature.java: 反序列化特性枚举,用于控制解析行为。
com.alibaba.fastjson.annotation (注解模块)
提供了一系列注解,允许用户通过声明式的方式精细地控制序列化和反序列化的行为。
- 关键注解 :
- @JSONField: 最核心的注解,可用于字段或方法上,用于自定义字段名、格式化、序列化 / 反序列化顺序、是否包含等。
- @JSONType: 可用于类上,用于配置该类的序列化器、反序列化器、特性开关等。
3.2 项目结构小结
Fastjson 框架在架构设计体现了 “关注点分离” 的原则,将序列化、反序列化、API、工具类等清晰地划分到不同的模块中。整个框架具有高度的可扩展性,用户可以通过 ObjectSerializer / ObjectDeserializer 接口和丰富的注解来满足各种复杂的定制化需求。
四、核心源码分析
为了更直观说明框架实现原理,本文对部分展示的源代码进行了删减,有些使用了伪代码,如需了解更多实现细节请读者阅读项目源码 (https://github.com/alibaba/fastjson)
整体上 Fastjson 通过统一的门面 API(JSON.toJSONString/parseObject)调用核心控制器(JSONSerializer/DefaultJSONParser),利用 ASM 字节码生成或反射机制,配合 SerializeWriter/JSONLexer 进行高效的 Java 对象与 JSON 字符串间双向转换,同时提供配置缓存、循环引用检测和 AutoType 安全防护等优化机制。下图为框架处理数据流:

数据流
4.1 序列化原理介绍
序列化步骤主要包括:序列化器查找→JavaBean 字段解析→字段值转换和 JSON 字符串构建等过程。下图为序列化处理时序图:

序列化时序图
序列化入口与初始化
使用 JSON.toJSONString () 入口,将 person 对象转换为 JSON 字符串。
Person person = new Person();
String json = JSON.toJSONString(person);
用户调用 toJSONString 方法进行对象序列化操作,JSON.java 包含了多个 toJSONString 重载方法,共同完成核心类初始化:SerializeConfig,SerializeWriter,JSONSerializer。
//用户不指定SerializeConfig,默认私有全局配置
public static String toJSONString(Object object, SerializeFilter[] filters,
SerializerFeature... features) {
return toJSONString(object, SerializeConfig.globalInstance, filters, null, DEFAULT_GENERATE_FEATURE, features);
}
public static String toJSONString(Object object,
SerializeConfig config,
SerializeFilter[] filters,
String dateFormat,
int defaultFeatures,
SerializerFeature... features) {
SerializeWriter out = new SerializeWriter((Writer) null, defaultFeatures, features);
try {
JSONSerializer serializer = new JSONSerializer(out);
//省略其他代码...
serializer.write(object); // 核心序列化调用
return out.toString();
} finally {
out.close();
}
}
序列化控制流程
JSONSerializer.write () 核心逻辑
write 方法的逻辑比较简单,首先处理 null 值,然后根据类型查找序列器 (ObjectSerializer),最后将序列化逻辑委派给序列化器处理。
public final void write(Object object) {
//如何序列化对象为null,直接写入"null"字符串
if (object == null) {
out.writeNull();
return;
}
Class<?> clazz = object.getClass();
ObjectSerializer writer = getObjectWriter(clazz); // 类型识别与序列化器选择
try {
writer.write(this, object, null, null, 0); // 委托给具体序列化器
} catch (IOException e) {
throw new JSONException(e.getMessage(), e);
}
}
类型识别与序列化器策略
框架采用策略化模式将不同类型序列化逻辑封装成不同的序列化器:
- 基础类型:使用专门的 Codec(如 StringCodec、IntegerCodec)
- 集合类型:使用 ListSerializer、MapSerializer 等
- JavaBean : 使用 JavaBeanSerializer 或 ASM 动态生成的序列化器
- 枚举类型:使用 EnumSerializer
SerializeConfig.getObjectWriter 方法负责序列化器查找工作:
public ObjectSerializer getObjectWriter(Class<?> clazz, boolean create) {
// 第一步:缓存查找
ObjectSerializer writer = get(clazz);
if (writer != null) {
return writer;
}
// 第二步:SPI扩展加载(当前线程类加载器)
try {
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
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) {
// 第三步:SPI扩展加载(JSON类加载器)
final ClassLoader classLoader = JSON.class.getClassLoader();
if (classLoader != Thread.currentThread().getContextClassLoader()) {
// 重复SPI加载逻辑...
}
}
// 第四步:模块扩展
for (Module module : modules) {
writer = module.createSerializer(this, clazz);
if (writer != null) {
put(clazz, writer);
return writer;
}
}
// 第五步:内置类型匹配
if (writer == null) {
String className = clazz.getName();
Class<?> superClass;
if (Map.class.isAssignableFrom(clazz)) {
put(clazz, writer = MapSerializer.instance);
} else if (List.class.isAssignableFrom(clazz)) {
put(clazz, writer = ListSerializer.instance);
} else if (Collection.class.isAssignableFrom(clazz)) {
put(clazz, writer = CollectionCodec.instance);
} else if (Date.class.isAssignableFrom(clazz)) {
put(clazz, writer = DateCodec.instance);
} else if (clazz.isEnum()) {
// 枚举处理逻辑
} else if (clazz.isArray()) {
// 数组处理逻辑
} else {
// 第六步:JavaBean序列化器创建
if (create) {
writer = createJavaBeanSerializer(clazz);
put(clazz, writer);
}
}
}
return writer;
}
JavaBean 序列化处理
JavaBeanSerializer 的 write 方法实现了 Java 对象序列化处理核心逻辑:
方法签名分析:
protected void write(JSONSerializer serializer, //JSON序列化器,提供序列化上下文和输出流
Object object, //待序列化的Java对象
Object fieldName, //字段名称,用于上下文追踪
Type fieldType, //字段类型信息
int features, //序列化特性标志位
boolean unwrapped //是否展开包装,用于嵌套对象处理
) throws IOException
序列化流程概览:
// 1. 空值检查和循环引用处理
if (object == null) {
out.writeNull();
return;
}
if (writeReference(serializer, object, features)) {
return;
}
// 2. 字段序列化器选择
final FieldSerializer[] getters;
if (out.sortField) {
getters = this.sortedGetters;
} else {
getters = this.getters;
}
// 3. 上下文设置和格式判断
SerialContext parent = serializer.context;
if (!this.beanInfo.beanType.isEnum()) {
serializer.setContext(parent, object, fieldName, this.beanInfo.features, features);
}
// 4.遍历属性序列化器,完成属性序列化
for (int i = 0; i < getters.length; ++i) {
FieldSerializer fieldSerializer = getters[i];
// 获取属性值
Object propertyValue = this.processValue(serializer, fieldSerializer.fieldContext, object, fieldInfoName,
propertyValue, features);
// 写入属性值
fieldSerializer.writeValue(serializer, propertyValue);
}
循环引用检测:
JavaBeanSerializerwriteReference 方法执行循环引用检测,Fastjson 使用 $ref 占位符处理循环引用问题,防止对象循环引用造成解析查询栈溢出。
public boolean writeReference(JSONSerializer serializer, Object object, int fieldFeatures) {
SerialContext context = serializer.context;
int mask = SerializerFeature.DisableCircularReferenceDetect.mask;
// 检查是否禁用循环引用检测
if (context == null || (context.features & mask) != 0 || (fieldFeatures & mask) != 0) {
return false;
}
// 检查对象是否已存在于引用表中
if (serializer.references != null && serializer.references.containsKey(object)) {
serializer.writeReference(object); // 写入引用标记
return true;
}
return false;
}
上下文管理与引用追踪:
序列化采用 DFS (深度优先) 算法遍历对象树,使用 IdentityHashMap<Object, SerialContext> references 来追踪对象引用:
- setContext: 建立序列化上下文,记录对象层次关系
- containsReference: 检查对象是否已被序列化
- popContext: 序列化完成后清理上下文
protected IdentityHashMap<Object, SerialContext> references = null;
protected SerialContext context;
//使用链表建立序列化上下文引用链,记录对象层次关系
public void setContext(SerialContext parent, Object object, Object fieldName, int features, int fieldFeatures) {
if (out.disableCircularReferenceDetect) {
return;
}
//构建当前上下文到parent上下文引用链
this.context = new SerialContext(parent, object, fieldName, features, fieldFeatures);
if (references == null) {
references = new IdentityHashMap<Object, SerialContext>();
}
this.references.put(object, context);
}
//检查对象是否已被序列化,防止重复序列化
public boolean containsReference(Object value) {
if (references == null) {
return false;
}
SerialContext refContext = references.get(value);
if (refContext == null) {
return false;
}
if (value == Collections.emptyMap()) {
return false;
}
Object fieldName = refContext.fieldName;
return fieldName == null || fieldName instanceof Integer || fieldName instanceof String;
}
//清理上下文,将当前序列化上下文指向父亲节点
public void popContext() {
if (context != null) {
this.context = this.context.parent;
}
}
字段值转换与序列化
FieldSerializer.writeValue () 核心逻辑
FieldSerializer 的 writeValue 方法实现了字段值的序列化操作:
public void writeValue(JSONSerializer serializer, Object propertyValue) throws Exception {
// 运行时类型识别
Class<?> runtimeFieldClass = propertyValue != null ?
propertyValue.getClass() : this.fieldInfo.fieldClass;
// 查找属性类型对应的序列化器
ObjectSerializer fieldSerializer = serializer.getObjectWriter(runtimeFieldClass);
// 处理特殊格式和注解
if (format != null && !(fieldSerializer instanceof DoubleSerializer)) {
serializer.writeWithFormat(propertyValue, format);
return;
}
// 委托给具体序列化器处理
fieldSerializer.write(serializer, propertyValue, fieldInfo.name,
fieldInfo.fieldType, fieldFeatures);
}
不同类型的序列化策略
基础类型序列化 :
- 直接调用 SerializeWriter 的对应方法(writeInt、writeString 等)
复杂对象序列化 :
- 递归调用 JSONSerializer.write () 方法
- 维护序列化上下文和引用关系
- 应用过滤器和特性配置
ASM 定制化序列化器加速,下文会进行详细讲解。
- 为序列化的类动态生成定制化的序列化器,避免反射调用开销
JSON 字符串构建
SerializeWriter.java 采用线程本地缓冲机制,提供高效的字符串构建:
//用于存储存JSON字符串
private final static ThreadLocal<char[]> bufLocal = new ThreadLocal<char[]>();
//将字符串转换为UTF-8字节数组
private final static ThreadLocal<byte[]> bytesBufLocal = new ThreadLocal<byte[]>();
- 字符缓冲区:线程本地 char [] 数组减少内存分配,避免频繁创建临时数组对象。
- 动态扩容:根据内容长度自动调整缓冲区大小。
bufLocal 初始化创建 2048 字符的缓冲区,回收阶段当缓冲区大小不超过 BUFFER_THRESHOLD (128KB)时,将其放回 ThreadLocal 缓存,超过阈值的大缓冲区不缓存,避免内存占用过大。
bytesBufLocal 专门用于 UTF-8 编码转换过程,初始缓冲区大小:8KB(1024 * 8),根据字符数量估算所需字节数(字符数 × 3),只有不超过 BUFFER_THRESHOLD 的缓冲区才会被缓存。
更多推荐


所有评论(0)