从 Akka actor 调用注入的 Scala class

Invoking an injected Scala class from an Akka actor

我在 Play for Scala 中有以下 class 注入另一个 class:

class MainEtl2 @Inject() (ic: injectedClass) {
    def run (option: String) = {
      ic.method1() 
      // ... some code
    }
}

我需要在 Akka Actor 中调用方法 run。这是我的尝试,假设 Guice 将在调用 MainEtl2 时注入 injectedClass

class MainEtl extends Actor {

  @Inject val me2 : MainEtl2

  def receive = {
    case option: String => {         
        val x = me2.run(option)
        // ... more code
        }
     } 
  }

MainEtl class 未编译并出现以下错误:

class MainEtl needs to be abstract, since value me2 is not defined

如何进行这项工作?

我会尝试注入 MainEtl2 类似于 CountingServicethis example 中的注入方式:

class MainEtl @Inject() (me2: MainEtl2) extends Actor {
  def receive = {
    case option: String => {         
      val x = me2.run(option)
      // ... more code
    }
  } 
}

虽然您指定了@Inject 注释,但您仍然需要一个初始值,guice 将在注入依赖项时覆盖该初始值,所以试试这个,

class MainEtl extends Actor {

  @Inject val me2 : MainEtl2 = null //initial value.

  def receive = {
    case option: String => {         
        val x = me2.run(option)
        // ... more code
        }
     } 
  }

我会根据Play documentation提出这样的解决方案。以这种方式定义你的演员:

class MainEtl @Inject() (me2: MainEtl2) extends Actor {
  def receive = {
    case option: String => {         
      val x = me2.run(option)
    }
  } 
}

定义具有 Akka 支持的播放模块并绑定命名演员:

class AkkaBindings extends AbstractModule with AkkaGuiceSupport {
  bindActor[MainEtl]("mainEtl")
}

通过添加

在 application.conf 中注册此模块
play.modules.enabled += "some.package.AkkaBindings"

现在您可以通过名称引用注入您的演员:

class Scheduler @Inject()(@Named("mainEtl") mainEtl: ActorRef) {
  //some code
  val scheduler = QuartzSchedulerExtension(system)
  scheduler.schedule("dailyproc", mainEtl, "abc", None)
}