【问题标题】:Guice dependency requiring references to Singleton inside AbstractModuleGuice 依赖需要在 AbstractModule 中引用 Singleton
【发布时间】:2017-08-30 14:27:34
【问题描述】:

我有一个在初始化客户端时需要隐式 ActorSystem 的外部库 (scala-redis)。我想在我的 Play (2.6) 应用程序中将我的 RedisClient 作为单例,因为将其作为单例是有意义的。

class CustomAppModule(environment: Environment,
                     configuration: Configuration) extends AbstractModule {
  def configure() = {
    //val system = getProvider(classOf[ActorSystem]).get()
    //val system = ActorSystem()
    //bind(classOf[ActorSystem]).toInstance(system)

    val redis = RedisClient(configuration.get[String]("redis.host"))(system)
    bind(classOf[RedisClient]).toInstance(redis)    
  }
}

第一个系统失败是因为“在创建 Injector 之前不能使用 Provider”,第二个系统失败是因为 Play Framework 在应用程序启动时初始化了 ActorSystem 本身,第二个系统失败是因为“绑定到 akka.actor。 ActorSystem 已在 play.api.inject.BuiltinModule 中配置。

那么,使用 Guice/DI 处理这种情况的惯用方式是什么?我是否需要一个以 RedisClient 作为值的包装器 Singleton,以及 ActorSystem 可以注入的位置?

【问题讨论】:

    标签: scala dependency-injection playframework guice


    【解决方案1】:

    我认为提供方法将解决您的问题。把你的模块写成

    class MyModule extends AbstractModule {
    
       def configure() = {
       }
    
       @Provides
       @Singleton
       def givePrecious() : MyClass  = {
          new MyClass()
       }
    }
    

    我的班级看起来像这样

    @Singleton 
    class MyClass(a: String) {
       def this()  = {
          this("a")
          println("constructor called")
       }
    }
    

    现在我尝试创建这个类的 3 个实例

    val injector = Guice.createInjector(new MyModule())
    val precious1 = injector.getInstance(classOf[MyClass])
    val precious2 = injector.getInstance(classOf[MyClass])
    val precious3 = injector.getInstance(classOf[MyClass])
    

    你会看到字符串“constructor called”只打印了一次。

    为了简单起见,我将 a 作为字符串。您可以尝试将其设为 ActorSystem 的实例。

    【讨论】:

      猜你喜欢
      • 2014-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-29
      • 2013-03-13
      • 2017-10-18
      • 1970-01-01
      相关资源
      最近更新 更多