本文介绍了Play Framework,Akka,Guice:如何在控制器内部使用Guice创建一个actor的多个实例(具有依赖项)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

播放框架文档中有一个示例( https://www.playframework. com/documentation/2.6.x/ScalaAkka )说明如何将actor(具有要注入的依赖项)注入控制器:

There is an example in play framework doc (https://www.playframework.com/documentation/2.6.x/ScalaAkka) that explains how to inject actor (which has dependencies to be injected) into controller:

@Singleton
class Application @Inject() 
(@Named("configured-actor") configuredActor: ActorRef)
(implicit ec: ExecutionContext) extends Controller {

      implicit val timeout: Timeout = 5.seconds

      def getConfig = Action.async {
        (configuredActor ? GetConfig).mapTo[String].map { message =>
          Ok(message)
        }
      }
    }

但是据我了解,它会创建一个actor的单个实例(例如singleton).

But as I understand, it creates a single instance of the actor (e.g., singleton).

我需要在控制器内创建configuredActor的多个实例.

I need to create multiple instances of configuredActor inside the controller.

还有一个示例演示了如何从父actor创建子actor(具有要注入的依赖项)实例

There is also an example which demonstrates how to create child actors (which has dependencies to be injected) instances from parent actor

object ParentActor {
  case class GetChild(key: String)
}

class ParentActor @Inject() (
    childFactory: ConfiguredChildActor.Factory
) extends Actor with InjectedActorSupport {
  import ParentActor._

  def receive = {
    case GetChild(key: String) =>
      val child: ActorRef = injectedChild(childFactory(key), key)
      sender() ! child
  }
}

我试图在控制器内部应用此技术,但是injectedChild(childFactory(key), key)需要(隐式)actor上下文

I've tried to apply this technique inside controller, but injectedChild(childFactory(key), key) requires (implicitly) actor context

def injectedChild(create: => Actor, name: String, props: Props => Props = identity)(implicit context: ActorContext): ActorRef = ...

但是我需要从ActorSysem(例如/user)创建这个actor.

But I need to create this actor from ActorSysem (e.g. /user).

(我本来想获得/user actor的上下文,但是如何?这是正确的吗?)

(I thought to get the context of /user actor, but how? is that correct?)

在父角色外部(例如,在控制器内部)使用Guice创建角色的多个实例的正确方法是什么?

What is a proper way to create multiple instances of an actor with Guice outside parent actor (for example, inside controller)?

推荐答案

我认为没有从演员外部获取ActorContext的方法,但是如果您想从/user演员创建子演员,可以直接system.actorOf做.

I don't think there is a way of obtaining the ActorContext from outside of an actor, but if you like to create child actors from the /user actor you could do directly system.actorOf.

问题就像您说的那样,InjectedActorSupport需要一个ActorContext.但是,如果您看一下特质,那就没什么花哨的了,只是

The problem is like you said, that InjectedActorSupport needs an ActorContext.But if you look the trait, it doesn't do anything fancy, just

  def injectedChild(create: => Actor, name: String, props: Props => Props = identity)(implicit context: ActorContext): ActorRef = {
    context.actorOf(props(Props(create)), name)
  }

因此,解决方案是扩展特征并添加一个接收ActorSystem而不是ActorContext的方法.

So, the solution is to extend the trait and add a method that receives the ActorSystem instead of the ActorContext.

  def injectedChild2(create: => Actor, name: String, props: Props => Props = identity)(implicit system: ActorSystem): ActorRef = {
    system.actorOf(props(Props(create)), name)
  }

实际上,您甚至可以直接将方法添加到控制器中,但是如果要在多个控制器中执行此操作将不方便.

In fact, you could even add the method to the controller directly but it is not convenient if you want to do this in multiples controllers.

更新:

尽管从技术上讲这是正确的,但我(正确地)认为这是缺乏接收ActorSystem的方法的目的.

although this is technically correct I assumed (correctly) that the lack of a method that receives an ActorSystem was intended.

因此,我已经向Play开发者团队提出了要求,詹姆斯·罗珀(James Roper)回答:

So, I've asked to the play dev team and James Roper has answered:

这篇关于Play Framework,Akka,Guice:如何在控制器内部使用Guice创建一个actor的多个实例(具有依赖项)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 13:56