三、项目结构

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 的缓冲区才会被缓存。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐