1. 简介
本文将深入探讨 Apache Avro 数据序列化/反序列化框架。重点学习如何在对象初始化和序列化时处理默认值的 schema 定义。
2. Avro 是什么?
Apache Avro 是传统数据格式的强力替代方案。它通常使用 JSON 定义 schema,在 Apache Kafka、Hive 或 Impala 等场景中广泛使用。Avro 特别适合处理实时大数据(写密集型操作)。
简单理解:Avro 由 JSON 格式的 schema 定义驱动。
核心优势: ✅ 数据自动压缩(节省 CPU 资源) ✅ 强类型系统(每个属性都需声明类型) ✅ 数据自带 schema ✅ 文档内嵌在 schema 中 ✅ 基于 JSON 实现跨语言支持 ✅ 安全的 schema 演进机制
3. Avro 环境搭建
首先添加 Avro Maven 依赖:
<dependencies>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>1.11.3</version>
</dependency>
</dependencies>
接着配置 avro-maven-plugin 辅助代码生成:
<build>
<plugins>
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.11.3</version>
<configuration>
<sourceDirectory>${project.basedir}/src/main/java/com/baeldung/avro/</sourceDirectory>
<outputDirectory>${project.basedir}/src/main/java/com/baeldung/avro/</outputDirectory>
<stringType>String</stringType>
</configuration>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
现在定义示例 schema(文件扩展名必须是 .avsc),这里命名为 car.avsc:
{
"namespace": "generated.avro",
"type": "record",
"name": "Car",
"fields": [
{ "name": "brand",
"type": "string"
},
{ "name": "number_of_doors",
"type": "int"
},
{ "name": "color",
"type": "string"
}
]
}
Schema 关键要素解析:
namespace
:生成类的包路径record
:特殊 Java 类型,比普通类更简洁(Avro 支持 6 种复杂类型:record、enum、array、map、union、fixed)fields
:重点!默认值就在这里配置
4. Avro 默认值处理
**核心要点:字段可通过 union 设为可选(默认 null),或指定具体默认值**。两种模式:
- 可选字段 → 默认 null
- 必填字段 → 使用 schema 定义的默认值
升级后的 schema 示例:
{
"namespace": "generated.avro",
"type": "record",
"name": "Car",
"fields": [
{ "name": "brand",
"type": "string",
"default": "Dacia"
},
{ "name": "number_of_doors",
"type": "int",
"default": 4
},
{ "name": "color",
"type": ["null", "string"],
"default": null
}
]
}
⚠️ 踩坑提醒:要使默认值生效,必须使用生成类的 newBuilder()
方法!测试用例演示:
@Test
public void givenCarJsonSchema_whenCarIsSerialized_thenCarIsSuccessfullyDeserialized() throws IOException {
Car car = Car.newBuilder()
.build();
SerializationDeserializationLogic.serializeCar(car);
Car deserializedCar = SerializationDeserializationLogic.deserializeCar();
assertEquals("Dacia", deserializedCar.getBrand());
assertEquals(4, deserializedCar.getNumberOfDoors());
assertNull(deserializedCar.getColor());
}
验证结果:
brand
默认为 "Dacia"number_of_doors
默认为 4color
因设为可选字段(union 类型)默认为 null
进阶技巧:强制字段为可选(即使原始类型是 int):
{
"name": "number_of_wheels",
"type": ["null", "int"],
"default": null
}
5. 总结
Avro 专为大数据场景的高效序列化而生。
本文系统介绍了: ✅ Avro 核心优势与搭建流程 ✅ 重点:Schema 默认值配置方案 ✅ 实际应用中的注意事项
完整代码示例见 GitHub 仓库。