我正在尝试在Akka
中创建基本的Actor,但是我发现了两种不同的创建actor的方法。一种方法是扩展akka.actor.Actor
特性并实现receive
方法,如下所示
import akka.actor.Actor
class HelloActor extends Actor {
override def receive: Receive = ???
}
其他方法是使用对象并实现如下所示的apply()
方法:
final case class GreetedMessage(whom: String, from: ActorRef[GreetMessage])
final case class GreetMessage(whom: String, replyTo: ActorRef[GreetedMessage])
object GreeterActor {
def apply(): Behavior[GreetMessage] = Behaviors.receive { (context, message) =>
context.log.info("Hello {}!", message.whom)
message.replyTo ! GreetedMessage(message.whom, context.self)
Behaviors.same
}
}
我想知道哪种方法是创建演员的首选方法,如果可能的话,其背后的原因。
我假设扩展Actor
特性是旧方法,因为Akka官方网站上未提及它。请加亮。
应注意,您的示例均未创建演员:这是ActorSystem
的工作。这些示例定义了参与者。
定义参与者的第一种方法是“经典”无类型的参与者API。
第二种方法是用于类型化参与者的两个API之一(特别是“功能性”样式API)。
Akka文档说:
对于新项目,我们建议使用新的[类型化的] Actor API。
经典的API仍将得到完全支持,并且可能会持续很长时间。
还有一个用于定义类型化actor的OO风格的API:
class GreeterBehavior(context: ActorContext[GreetMessage]) extends AbstractBehavior[GreetMessage](context) {
override def onMessage(message: GreetMessage): Behavior[GreetMessage] = {
context.log.info("Hello {}!", message.whom)
message.replyTo ! GreetedMessage(message.whom, context.self)
this
}
}
编辑以添加:经典API已被完整记录,例如Akka docs for Actors。
类型化的API使编译器可以验证至少一些消息传递协议。如果您有ActorRef[Foo]
,则只能向演员发送Foo
(包括Foo
的子类型)的消息。也可以验证参与者的行为是否涵盖了它可能收到的所有消息。