在 Actor 外部创建 actor

Akka Typed 已不允许通过 ActorSystem 的实例来创建 actor,推荐使用自定义的根 actor 来初始化整个 actor 树,并在构建 ActorSystem 时作为守卫 Behavior 传入:

val behavior: Behavior[T] = _ // 根actor,用于构建整个actor业务树
val system = ActorSystem(behavior, "typed")

但实际应用中,或许有充分的理由需要通过 ActorSystem 来创建actor,这有两种方式来实现:

  • 使用 SpawnProtocol
  • 为守卫actor提供自定义 Spawn 消息

使用 SpawnProtocol

使用 Akka 内置的 SpawnProtocol 作为 ActorSystem 的初始化 Behavior,就可以通过 SpawnProtocol.Spawn 消息来创建actor。

implicit val system = ActorSystem(SpawnProtocol(), "spawn-protocol")
implicit val timeout = Timeout(2.seconds)
val pingF = system.ask[ActorRef[Ping.Command]](replyTo => SpawnProtocol.Spawn(Ping(), "ping", Props.empty, replyTo))
val ping = Await.result(pingF, 2.seconds)
ping ! Ping.Start
system.terminate()

为守卫 actor 提供自定义 Spawn 消息

使用 SpawnProtocol 虽然可以在ActorSystem外部创建actor,但却没法使用我们自己定义的守卫actor了。参照 SpawnProtocol.Spawn 为自己的守卫 actor 提供 Spawn 消息,这样就可以在 ActorSystem 外部创建 actor 了。

object RootActor {
  sealed trait Command
  case class Spawn[T](behavior: Behavior[T], name: String, props: Props, replyTo: ActorRef[ActorRef[T]]) extends Command
  // 在此添加其它业务消息

  def apply(): Behavior[Command] = Behaviors.receive {
    case (context, Spawn(behavior, name, props, replyTo)) =>
      replyTo ! context.spawn(behavior, name, props)
      Behaviors.same
  }
}

通过此方式创建的所有actor都是守卫actor的子actor。

在此文档中发现错误?该页面的源代码可以在 这里 找到。欢迎随时编辑并提交Pull Request。