跨语言序列化
Apache Fory™ 通过 xlang 序列化格式支持 Java 和其他语言(Python、Rust、Go、JavaScript 等)之间的无缝数据交换。这使得多语言微服务、多语言数据管道和跨平台数据共享成为可能。
启用跨语言模式
要序列化供其他语言使用的数据,使用 Language.XLANG 模式:
import org.apache.fory.*;
import org.apache.fory.config.*;
// 使用 XLANG 模式创建 Fory 实例
Fory fory = Fory.builder()
.withLanguage(Language.XLANG)
.withRefTracking(true) // 为复杂图启用引用跟踪
.build();
为跨语言兼容性注册类型
类型必须使用一致的 ID 或名称在所有语言中注册。Fory 支持两种注册方法:
按 ID 注册(推荐用于性能)
public record Person(String name, int age) {}
// 使用数字 ID 注册 - 更快更紧凑
fory.register(Person.class, 1);
Person person = new Person("Alice", 30);
byte[] bytes = fory.serialize(person);
// bytes 可以被 Python、Rust、Go 等反序列化。
优点:更快的序列化,更小的二进制大小 权衡:需要协调以避免跨团队/服务的 ID 冲突
按名称注册(推荐用于灵活性)
public record Person(String name, int age) {}
// 使用字符串名称注册 - 更灵活
fory.register(Person.class, "example.Person");
Person person = new Person("Alice", 30);
byte[] bytes = fory.serialize(person);
// bytes 可以被 Python、Rust、Go 等反序列 化。
优点:不容易冲突,跨团队管理更容易,无需协调 权衡:由于字符串编码,二进制大小稍大
跨语言示例:Java ↔ Python
Java(序列化器)
import org.apache.fory.*;
import org.apache.fory.config.*;
public record Person(String name, int age) {}
public class Example {
public static void main(String[] args) {
Fory fory = Fory.builder()
.withLanguage(Language.XLANG)
.withRefTracking(true)
.build();
// 使用一致的名称注册
fory.register(Person.class, "example.Person");
Person person = new Person("Bob", 25);
byte[] bytes = fory.serialize(person);
// 通过网络/文件/队列将 bytes 发送到 Python 服务
}
}
Python(反序列化器)
import pyfory
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: pyfory.int32
# 在 xlang 模式下创建 Fory
fory = pyfory.Fory(ref_tracking=True)
# 使用与 Java 相同的名称注册
fory.register_type(Person, typename="example.Person")
# 从 Java 反序列化 bytes
person = fory.deserialize(bytes_from_java)
print(f"{person.name}, {person.age}") # 输出:Bob, 25
处理循环引用和共享引用
启用引用跟踪时,跨语言模式支持循环引用和共享引用:
public class Node {
public String value;
public Node next;
public Node parent;
}
Fory fory = Fory.builder()
.withLanguage(Language.XLANG)
.withRefTracking(true) // 循环引用需要
.build();
fory.register(Node.class, "example.Node");
// 创建循环引用
Node node1 = new Node();
node1.value = "A";
Node node2 = new Node();
node2.value = "B";
node1.next = node2;
node2.parent = node1; // 循环引用
byte[] bytes = fory.serialize(node1);
// Python/Rust/Go 可以正确反序列化这个,并保留循环引用
类型映射考虑
并非所有 Java 类型在其他语言中都有等价物。使用 xlang 模式时: