2017-08-30 93 views
0

我有一個外部庫(scala-redis),在初始化客戶端時需要隱式的ActorSystem。我想在我的Play(2.6)應用程序中將我的RedisClient作爲Singleton,因爲將它作爲Singleton是有意義的。需要引用AbstractModule中Singleton的Guice依賴關係

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)  
    } 
} 

第一個系統出現故障,因爲「供應商不能使用,直到注射器已創建」,因爲播放框架初始化ActorSystem本身第二系統出現故障時,應用程序啓動,以及第二系統失敗的原因爲「結合akka.actor.ActorSystem已經在play.api.inject.BuiltinModule中配置「。

那麼與Guice/DI開展這種情況的慣用方式是什麼?我是否需要一個包含RedisClient作爲值的包裝Singleton,以及可以注入ActorSystem的位置?

回答

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]) 

你會看到字符串「之稱的構造」只打印一次。

爲了簡單起見,我已將字符串作爲a。你可以嘗試使它成爲ActorSystem的一個實例。