是否可以为akka编写upickle序列化器

时间:2020-09-05 15:13:47

标签: scala akka upickle

我想使用upickle实现akka序列化器,但是我不确定它是否可行。为此,我需要实现一个类似于以下内容的序列化器:

import akka.serialization.Serializer
import upickle.default._

class UpickleSerializer extends Serializer {

    def includeManifest: Boolean = true
    def identifier = 1234567

    def toBinary(obj: AnyRef): Array[Byte] = {
        writeBinary(obj) // ???
    }

    def fromBinary(bytes: Array[Byte], clazz: Option[Class[_]]): AnyRef = {
        readBinary(bytes) // ???
    }
}

问题是没有相关的Writer / Reader,我无法调用writeBinary / readBinary。有没有一种方法可以根据对象类查找这些对象?

2 个答案:

答案 0 :(得分:0)

看看以下文件,您应该有一些想法!

CborAkkaSerializer.scala

LocationAkkaSerializer.scala

注意:这些序列化程序正在使用cbor

答案 1 :(得分:0)

我找到了一种使用反射的方法。我基于以下假设假设该解决方案:任何需要序列化的对象都应在其伴随对象中定义一个ReadWriter:

class UpickleSerializer extends Serializer {

private var map = Map[Class[_], ReadWriter[AnyRef]]()

def includeManifest: Boolean = true
def identifier = 1234567

def toBinary(obj: AnyRef): Array[Byte] = {
    implicit val rw = getReadWriter(obj.getClass)
    writeBinary(obj)
}

def fromBinary(bytes: Array[Byte], clazz: Option[Class[_]]): AnyRef = {
    implicit val rw = lookup(clazz.get)
    readBinary[AnyRef](bytes)
}

private def getReadWriter(clazz: Class[_]) = map.get(clazz) match {
    case Some(rw) => rw
    case None =>
        val rw = lookup(clazz)
        map += clazz -> rw
        rw
}

private def lookup(clazz: Class[_]) = {
    import scala.reflect.runtime._
    val rootMirror = universe.runtimeMirror(clazz.getClassLoader)
    val classSymbol = rootMirror.classSymbol(clazz)
    val moduleSymbol = classSymbol.companion.asModule
    val moduleMirror = rootMirror.reflectModule(moduleSymbol)
    val instanceMirror = rootMirror.reflect(moduleMirror.instance)
    val members = instanceMirror.symbol.typeSignature.members
    members.find(_.typeSignature <:< typeOf[ReadWriter[_]]) match {
        case Some(rw) =>
            instanceMirror.reflectField(rw.asTerm).get.asInstanceOf[ReadWriter[AnyRef]]
        case None =>
            throw new RuntimeException("Not found")
    }
}

}

相关问题