配置
本页介绍 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 载荷,必须:
- 使用
ForyScala.builder().withXlang(false)创建运行时,或者通过Fory.builder().withXlang(false).withModule(ForyScala)安装ForyScala。 - 序列化前注册应用类。
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 使用规范的 list、set 和 map 载荷,而不是 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 配置。