如何在应用程序中访问Play Framework 2.4 guice Injector?

时间:2016-01-19 05:57:25

标签: java scala playframework playframework-2.0 guice

我想在Play Framework 2.4中使用Guice getInstance类的Injector方法,如何访问它?

我使用Guice FactoryModuleBuilder来实现一个在运行时返回另一个工厂的工厂!在返回工厂的第二级,我需要访问Play Guice Injector以使用反射而不是@Inject注释来手动获取对象。

5 个答案:

答案 0 :(得分:16)

有很多方法。我用这个。

编辑:这与Play版本的< = 2.4:

相关
Play.maybeApplication.map(_.injector.instanceOf[MyProdClass]).getOrElse(new MyDevClass)

Play.current.injector.instanceOf[MyClass]

对于> = 2.5的版本:

import play.api.inject.Injector
import javax.inject.Inject

class MyService @Inject() (injector: Injector) ={
    val myClassInstance = injector.instanceOf[MyClass]
    //do stuff
}

答案 1 :(得分:7)

使用Play Framework 2.5.x {@ 1}}已被弃用,DI应该始终是首选。因此,获取注入器实例的正确方法是使用:

play.api.Play.current

即使使用DI Provider类进行此操作也适用于我:)

答案 2 :(得分:5)

最好注射Guice Injector:

Play.application().injector().instanceOf(YourClass.class);

或者您可以将此代码用于Play Framework Java版:

data.toSource()

答案 3 :(得分:4)

除了其他Play 2.5.x解决方案之外,您可能希望在不使用注入的情况下在对象中获取Injector。例如,当您使用Scala单例时,@ inject可能无法正常工作。

在这种情况下,您可以使用:

@Singleton
class GlobalContext @Inject()(injector: Injector) {
  GlobalContext.injector = injector
}

object GlobalContext {
  private var injector: Injector = null  
}

使用Guice模块将单例设置为急切,否则不会自动初始化:

// Module.scala
class Module extends AbstractModule {
  override def configure() = {
    // ...

    // Eager initialize Context singleton
    bind(classOf[GlobalContext]).asEagerSingleton()
  }
}

答案 4 :(得分:1)

我非常喜欢Devabc's solution,因为肯定有一些场景无法依赖构造函数注入来获取注入器本身,而在Play 2.5.x中你必须使用已弃用的{{1}代码来获取注入器。

他的解决方案创建了对Play内置注入器的引用,并将其放入Scala对象中,可以在需要时由任何组件导入。辉煌!

然而,为了使它工作,对象需要提供一个公共接口来获取注入器,所以这里是我修改过的代码来修复它并演示如何使用它。

play.api.Play.current.Injector

初始化部分是相同的。

import play.api.inject.Injector
import javax.inject.Inject

@Singleton
class GlobalContext @Inject()(playInjector: Injector) {
  GlobalContext.injectorRef = playInjector
}

object GlobalContext {
  private var injectorRef: Injector = _

  def injector: Injector = injectorRef
}

客户端代码非常简单。在任何需要注射器的组件中:

// InjectionModule.scala
package modules

class InjectionModule extends AbstractModule {
  override def configure() = {
    // ...

    // Eager initialize Context singleton
    bind(classOf[GlobalContext]).asEagerSingleton()
  }
}

// application.conf
play.modules.enabled += "modules.InjectionModule"