【问题标题】:Inject service with Guice to child actor provided by factory为工厂提供的童演员注入 Guice 服务
【发布时间】:2016-04-19 20:01:21
【问题描述】:

在我的应用程序中,我有一个创建一些工人的主管。这些工作人员中的每一个都需要两个 QueueClients 实例(具有不同的配置和工作人员之间的不同实例)。我是 guice 的新手,在将这些依赖项注入子演员时遇到了问题。

这是我的工人阶级:

object LegacyConsumer {

  trait Factory {
    def apply(): Actor
  }

}

class LegacyConsumer @Inject()(
  eventsClient: QueueClient,
  deadLetterClient: QueueClient
) extends Actor with ActorLogging {

  override def preStart(): Unit = {
    log.error("prestart")
    log.error(eventsClient.toString)
  }

  def receive: PartialFunction[Any, Unit] = {
    case _ =>
      log.error("received message consumer")
  }
}

如您所见,我需要两个 QueueClients 来构建:

trait QueueClient {
...

  def numMessages: Int
}

class SqsClient @Inject()(name: String, key: String, secret: String, zone: String) extends Logging with QueueClient {
...
}

这就是我尝试创建工人的方式

class LegacyConsumerSupervisor @Inject()(
  consumerFactory: LegacyConsumer.Factory,
  @Named("numWorkers") workers: Int
)
  extends Actor with ActorLogging with InjectedActorSupport {

  override def preStart(): Unit = {
    (1 to workers).foreach { workerNumber =>
      val key = s"WORKER-$workerNumber"
      injectedChild(consumerFactory(), key, _.withDispatcher("akka.legacy-consumer-dispatcher"))
    }
  }

最后这就是我的绑定的样子

class ChatModule extends AbstractModule with ScalaModule with AkkaGuiceSupport{
  override def configure() {
    bind[Actor].annotatedWith(Names.named(LegacyConsumerSupervisor.name)).to[LegacyConsumerSupervisor]

    bind(classOf[Int])
      .annotatedWith(Names named "numWorkers")
      .toInstance(ConfigurationHelper.getInt("chat.legacy.num-workers"))

    bindActorFactory[LegacyConsumer, LegacyConsumer.Factory]

    bind(classOf[QueueClient])
//      .annotatedWith(Names named "legacyEventsClient")
        .toInstance(
          new SqsClient(
            ConfigurationHelper.getString("chat.legacy.events.name"),
            ConfigurationHelper.getString("chat.legacy.events.key"),
            ConfigurationHelper.getString("chat.legacy.events.secret"),
            ConfigurationHelper.getString("chat.legacy.events.region")
          )
        )

    bind(classOf[QueueClient])
//      .annotatedWith(Names named "legacyDeadLetterClient")
        .toInstance(
          new SqsClient(
            ConfigurationHelper.getString("chat.legacy.dead-letter.name"),
            ConfigurationHelper.getString("chat.legacy.dead-letter.key"),
            ConfigurationHelper.getString("chat.legacy.dead-letter.secret"),
            ConfigurationHelper.getString("chat.legacy.dead-letter.region")
          )
        )
  }
}

如何将不同的队列客户端实例注入每个工作人员?所有 legacyEventsClients 和 legacyDeadLetterClients 具有相同的配置(基于类型安全配置)。解决方案是否与辅助注射有关?

我现在遇到的错误:

已经在 ...configure(ChatModule.scala:29) 处配置了与 ...QueueClient 的绑定。 在 ...配置(ChatModule.scala:40)

所以我认为问题在于尝试将相同的绑定两次注入不同的实例...我尝试使用命名参数但随后将相同的客户端实例注入到每个 LegacyConsumer

问候

【问题讨论】:

    标签: scala akka guice


    【解决方案1】:

    我终于做到了,并且成功了:

    绑定:

        bind(classOf[QueueClient])
          .annotatedWith(Names named "legacyEventsClient")
          .toProvider(new Provider[SqsClient] {
            override def get = {
              new SqsClient(
                ConfigurationHelper.getString("chat.legacy.events.name"),
                ConfigurationHelper.getString("chat.legacy.events.key"),
                ConfigurationHelper.getString("chat.legacy.events.secret"),
                ConfigurationHelper.getString("chat.legacy.events.region")
              )
            }
          })
    
        bind(classOf[QueueClient])
          .annotatedWith(Names named "legacyDeadLetterClient")
          .toProvider(new Provider[SqsClient] {
            override def get = {
              new SqsClient(
                ConfigurationHelper.getString("chat.legacy.dead-letter.name"),
                ConfigurationHelper.getString("chat.legacy.dead-letter.key"),
                ConfigurationHelper.getString("chat.legacy.dead-letter.secret"),
                ConfigurationHelper.getString("chat.legacy.dead-letter.region")
              )
            }
          })
    

    在我的工人阶级中:

    class LegacyConsumer @Inject()(
      @Named("legacyEventsClient") eventsClient: QueueClient,
      @Named("legacyDeadLetterClient") deadLetterClient: QueueClient
    ) extends Actor with ActorLogging {
    
      override def preStart(): Unit = {
        log.error("prestart")
      }
    
      def receive: PartialFunction[Any, Unit] = {
        case _ =>
          log.error("received message consumer")
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-18
      • 2015-07-22
      • 2016-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多