首页 > 解决方案 > 使用带有 akka 道具的 Guice - 找不到合适的演员构造函数

问题描述

我有 kafkaProducer 演员:

class KafkaProducerActor @Inject()(
  avroProducer: MyKafkaProducerAvro,
  jsonProducer: MyKafkaProducerJson,
  metrics: PrometheusMetricsService
)
  extends Actor
{
  def handleErrs(block: => Unit): Unit = {
    try {
      block
    } catch {
      case e: Exception =>
        Logger.error(s"failed to produce kafka message, error: ${e.getMessage}, cause: ${ExceptionUtils.getRootCause(e)}, stacktrace: ${ExceptionUtils.getStackTrace(e)}")
        metrics.incKafkaErrorCounter(e.getClass.getName)
    }
  }

  override def receive: Receive = {
    case rec: ProducerRecord[GenericRecord, GenericRecord] =>
      handleErrs(avroProducer.produce(rec))

    case ProducerRecordJson(topic, key, content) =>
      handleErrs(jsonProducer.produce(new ProducerRecord[String, String](topic, key, content)))
  }
}

另外,我正在尝试使用actorSystem来获取actorRef:

  val kafka: ActorRef = actorSystem.actorOf(KafkaProducerActor.props, name = "kafkaProducerActor")

为此,我在 KafkaProducerActor 中定义:

object KafkaProducerActor {
  def props: Props = Props(classOf[KafkaProducerActor])
}

警告以下内容:

找不到合适的actor构造函数动态调用可以用构造函数调用替换

当用构造函数调用替换动态调用时(如编译器建议的那样),即:

object KafkaProducerActor {
  def props: Props = Props(new KafkaProducerActor())
}

我得到编译错误:

未指定值参数:avroProducer:MyKafkaProducerAvro,jsonProducer:MyKafkaProducerJson,metrics:PrometheusMetricsService

在这种情况下启动道具的正确方法是什么?

标签: scalaapache-kafkaakkaguice

解决方案


您应该在调用的上下文中注入您的服务,KafkaProducerActor.props并将其作为参数传递。

或者只是手动将其注入构造函数,但您需要为此进行静态全局注入。你可以用这样的助手来实现它:

object InjectHelper {
    lazy val injector: Injector = {
        val moduleInstance: com.google.inject.Module = ??? // somehow get  your guice module
        Guice.createInjector(moduleInstance)
    }

    def inject[T](implicit mf: Manifest[T]): T =
        InjectHelper.injector.getInstance(mf.runtimeClass).asInstanceOf[T]
}

object KafkaProducerActor {
  def props: Props = Props(
    new KafkaProducerActor(
      InjectHelper.inject[MyKafkaProducerAvro],
      InjectHelper.inject[MyKafkaProducerJson],
      InjectHelper.inject[PrometheusMetricsService]
    )
  )
}

推荐阅读