Fory 创建
本页介绍创建 Fory 实例的 Scala 特定要求。
基础设置
使用 Fory 进行 Scala 序列化时,必须:
- 通过
withScalaOptimizationEnabled(true)启用 Scala 优化 - 通过
ScalaSerializers.registerSerializers(fory)注册 Scala 序列化器
import org.apache.fory.Fory
import org.apache.fory.serializer.scala.ScalaSerializers
val fory = Fory.builder()
.withScalaOptimizationEnabled(true)
.build()
// 为 Scala 注册优化的 Fory 序列化器
ScalaSerializers.registerSerializers(fory)
注册 Scala 内部类型
根据序列化的对象类型,可能需要注册一些 Scala 内部类型:
fory.register(Class.forName("scala.Enumeration.Val"))
为避免这种注册,可以禁用类注册:
val fory = Fory.builder()
.withScalaOptimizationEnabled(true)
.requireClassRegistration(false)
.build()
注意:禁用类注册允许反序列化未知类型。这更加灵活,但如果类包含恶意代码可能不安全。
引用跟踪
循环引用在 Scala 中很常见。应该使用 withRefTracking(true) 启用引用跟踪:
val fory = Fory.builder()
.withScalaOptimizationEnabled(true)
.withRefTracking(true)
.build()
注意:如果不启用引用跟踪,在某些 Scala 版本中序列化 Scala Enumeration 时可能会出现 StackOverflowError。
线程安全
Fory 实例的创建成本不低。实例应该在多次序列化之间共享。
单线程使用
import org.apache.fory.Fory
import org.apache.fory.serializer.scala.ScalaSerializers
object ForyHolder {
val fory: Fory = {
val f = Fory.builder()
.withScalaOptimizationEnabled(true)
.build()
ScalaSerializers.registerSerializers(f)
f
}
}
多线程使用
对于多线程应用程序,使用 ThreadSafeFory:
import org.apache.fory.ThreadSafeFory
import org.apache.fory.ThreadLocalFory
import org.apache.fory.serializer.scala.ScalaSerializers
object ForyHolder {
val fory: ThreadSafeFory = new ThreadLocalFory(classLoader => {
val f = Fory.builder()
.withScalaOptimizationEnabled(true)
.withClassLoader(classLoader)
.build()
ScalaSerializers.registerSerializers(f)
f
})
}
配置选项
Fory Java 的所有配置选项都可用。查看 Java 配置选项获取完整列表。
Scala 的常用选项:
import org.apache.fory.Fory
import org.apache.fory.config.CompatibleMode
import org.apache.fory.serializer.scala.ScalaSerializers
val fory = Fory.builder()
.withScalaOptimizationEnabled(true)
// 为循环引用启用引用跟踪
.withRefTracking(true)
// 启用 schema 演化支持
.withCompatibleMode(CompatibleMode.COMPATIBLE)
// 启用异步编译以获得更好的启动性能
.withAsyncCompilation(true)
.build()
ScalaSerializers.registerSerializers(fory)