跳到主要内容
版本:1.1.0

配置

本页介绍 Scala 专用的运行时配置和 Fory 实例创建。

Xlang 设置

Fory Scala 遵循 Java builder 默认值:启用 xlang 模式,并使用兼容 Schema 演进。跨语言 Scala 载荷、schema IDL 生成的 Scala models,以及 macro-derived xlang serializers 都应使用这一路径。

import org.apache.fory.scala.ForyScala

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

序列化前注册应用类:

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

Native 模式设置

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

  1. 使用 ForyScala.builder().withXlang(false) 创建运行时,或者通过 Fory.builder().withXlang(false).withModule(ForyScala) 安装 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().withXlang(false)
.withRefTracking(true)
.build()

注意:如果未启用引用跟踪,在序列化 Scala Enumeration 时,某些 Scala 版本可能出现 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 native-mode 载荷的常用配置项:

import org.apache.fory.scala.ForyScala

val fory = ForyScala.builder().withXlang(false)
// 为循环引用启用引用跟踪
.withRefTracking(true)
// 为 native-mode 载荷启用 Schema 演进支持
.withCompatible(true)
// 启用异步编译以获得更好的启动性能
.withAsyncCompilation(true)
.build()

Xlang 模式

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

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

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

在 xlang 模式下,Scala collections 使用规范的 listsetmap 载荷,而不是 Scala factory 载荷。生成的 optional 字段使用 Option[T]

安全

Scala 使用 Java 运行时配置表面。生产环境以及任何不受信任的载荷来源都应保持启用类注册:

val fory = ForyScala.builder()
.requireClassRegistration(true)
.withMaxDepth(50)
.build()

安全相关配置:

  • 保持 requireClassRegistration(true),并注册应用类或生成的 modules。
  • 使用 withMaxDepth(...) 拒绝异常深的对象图。
  • Allow-listing 和 unknown-class 控制请遵循 Java 配置