跳到主要内容
版本:dev

配置

本页介绍 Scala 特有的 Fory 实例配置和创建方式。

Xlang 设置

Fory Scala 遵循 Java builder 的默认设置:使用带兼容 Schema 演进的 xlang 模式。 跨语言 Scala 载荷、Schema IDL 生成的 Scala 模型以及宏派生的 xlang 序列化器都应使用此路径。

import org.apache.fory.scala.ForyScala

val fory = ForyScala.builder()
.withXlang(true)
.build()

序列化之前请注册应用类:

fory.register(classOf[Person])
fory.register(classOf[Point])

原生模式设置

对于需要 JVM 原生对象行为的同语言 Scala/JVM 载荷,必须:

  1. 使用 ForyScala.builder().withXlang(false) 创建 Fory 实例,或者安装 ForyScala; 后一种方式使用 Fory.builder().withXlang(false).withModule(ForyScala)
  2. 序列化之前注册应用类。
import org.apache.fory.scala.ForyScala

val fory = ForyScala.builder().withXlang(false)
.build()

注册 Scala 内部类型

根据所序列化的对象类型,可能需要注册一些 Scala 内部类型:

fory.register(Class.forName("scala.Enumeration.Val"))

要避免此类注册,可以禁用类注册:

val fory = ForyScala.builder().withXlang(false)
.requireClassRegistration(false)
.build()

注意:禁用类注册后可以反序列化未知类型。这样更灵活,但如果类中包含恶意代码,则可能不安全。

引用跟踪

循环引用在 Scala 中很常见。应使用 withRefTracking(true) 启用引用跟踪:

val fory = ForyScala.builder()
.withRefTracking(true)
.build()

注意:如果不启用引用跟踪,某些 Scala 版本在序列化 Scala Enumeration 时可能发生 StackOverflowError

线程安全

创建 Fory 实例的开销并不低。应在多次序列化之间共享实例。

单线程用法

import org.apache.fory.Fory
import org.apache.fory.scala.ForyScala

object ForyHolder {
val fory: Fory = ForyScala.builder()
.withXlang(true)
.build()
}

多线程用法

对于多线程应用,请使用 ThreadSafeFory

import org.apache.fory.ThreadSafeFory
import org.apache.fory.scala.ForyScala

object ForyHolder {
val fory: ThreadSafeFory = ForyScala.builder()
.withXlang(true)
.buildThreadSafeFory()
}

配置选项

Fory Java 的所有配置选项均可用。完整列表请参阅 Java 配置

Scala 原生模式载荷的常用选项:

import org.apache.fory.scala.ForyScala

val fory = ForyScala.builder().withXlang(false)
// Enable reference tracking for circular references
.withRefTracking(true)
// Same-schema optimization. Use only when every reader and writer
// always uses the same Scala/JVM schema.
.withCompatible(false)
// Enable async compilation for better startup performance
.withAsyncCompilation(true)
.build()

对象图内存预算

Scala 使用 Java 的 withMaxGraphMemoryBytes(...) 选项。它为一次根反序列化设置近似的 对象图内存限制,主要针对实体化的集合、map、数组、结构体和对象。字符串、二进制数据、 基本类型标量和稠密基本类型数组等叶子值不计入其中,因此实际进程内存可能高于此值。 叶子值仍受剩余输入字节限制:如果未读输入没有足够的字节,Fory 不会读取或创建该叶子值。

val fory = ForyScala.builder()
.withMaxGraphMemoryBytes(128L * 1024 * 1024)
.withMaxUnbackedContainerItems(8192)
.build()

withMaxUnbackedContainerItems(...) 限制一次根反序列化中重复读取主体未消耗相应输入的 集合元素和 map 条目。默认值为 8192;零表示严格限制。

Xlang 模式

对于 Scala xlang 或 Schema IDL 生成的代码,请使用默认 xlang 模式并注册生成的 Schema 模块:

import org.apache.fory.scala.ForyScala
import example.ExampleForyModule

val fory = ForyScala.builder()
.withXlang(true)
.withRefTracking(true)
.withModule(ExampleForyModule)
.build()

在 xlang 模式下,Scala 集合使用规范的 listsetmap 载荷,而不是 Scala 工厂 载荷。生成的可选字段使用 Option[T]

兼容模式

Java builder 在 xlang 和原生模式下都默认启用兼容模式。当模型可能独立演进、服务分别 部署,或 xlang Schema 由不同语言手写时,请保留此默认设置。

只有在反序列化每个载荷所用的类 Schema 始终与序列化时相同,并且希望获得更快的序列化 速度和更小的体积时,才使用 withCompatible(false)。对于 xlang 载荷,只有在确认所有 语言使用相同 Schema 后,或者原生类型由 Fory Schema IDL 生成时,才调用 withCompatible(false)

安全

有关信任边界、安全的读取端配置和验证方法,请参阅 Scala 安全