我正在Play Framework(Scala)中尝试一些示例。我正在将一个演员注入控制器。
配置
我有以下代码:
的 ExampleController
class ExampleController @Inject() (
controllerComponents: ControllerComponents,
@Named("injected-router") injectedRouterActor: ActorRef,
@Named("injected") injectedActor: ActorRef)
extends AbstractController(controllerComponents) {
def alive = Action {
injectedActor ! "Hi from Example"
injectedRouterActor ! "Hi From Example to Router"
Ok("Alive")
}
}
InjectedActor
class InjectedActor extends Actor {
val name = s"IA-${self.path}-${System.nanoTime}"
println(s"constructor: $name")
def receive = {
case m => println(s"$name received: $m")
}
override def preStart() = {
println(s"preStart: $name")
super.preStart()
}
}
InjectedRouterActor
class InjectedRouterActor extends Actor {
val name = s"IRA-${self.path}-${System.nanoTime}"
println(s"constructor: $name")
def receive = {
case m => println(s"$name received: $m")
}
override def preStart() = {
println(s"preStart: $name")
super.preStart()
}
}
ChildActor
class ChildActor extends Actor {
val name = s"CH-${self.path}-${System.nanoTime}"
println(s"constructor: $name")
def receive = {
case m => println(s"$name received: $m")
}
}
模块
class BindingModule extends AbstractModule with AkkaGuiceSupport {
def configure = {
bindActor[InjectedActor]("injected")
bindActor[InjectedRouterActor]("injected-router", _ => RoundRobinPool(5).props(Props[ChildActor]))
}
}
当我运行此命令并点击 alive 的路线时,我会在控制台上看到所有演员的 println ,但 InjectedRouterActor 除外。
无法理解为什么?任何帮助表示赞赏。
由于
答案 0 :(得分:0)
在Akka中,路由器是您未明确实现的特殊实现参与者。
在您的示例中RoundRobinPool(5).props(Props[ChildActor])
创建Props
,它将创建循环池路由器,路由器为ChildActor
类型的actor。你真的不需要InjectedRouterActor
。如果要根据配置创建路由器,您可能仍希望拥有它(请参阅Akka docs中的示例)。
如果你看一下使用Guice helper时创建actor的ActorRefProvider
的来源
class ActorRefProvider[T <: Actor: ClassTag](name: String, props: Props => Props) extends Provider[ActorRef] {
@Inject private var actorSystem: ActorSystem = _
@Inject private var injector: Injector = _
lazy val get = {
val creation = Props(injector.instanceOf[T])
actorSystem.actorOf(props(creation), name)
}
}
您可以看到它创建了默认Props
,它从注入器获取InjectedRouterActor
的实例(类型信息作为T
类型参数传递)但是,因为您提供了{{ 1}}作为忽略函数参数的函数(props
),它将忽略_ => RoundRobinPool(5).props(Props[ChildActor])
变量。另外creation
作为名称参数传递给injector.instanceOf[T]
,因此不会立即调用它,因此不会创建Props#apply
。
您可以手动创建<{1}},而不是为InjectedRouterActor
中的路由器角色创建绑定:
configure