我有一个外部库(scala-redis),在初始化客户端时需要隐式ActorSystem。我想在我的Play(2.6)应用程序中将我的RedisClient作为Singleton,因为将它作为Singleton是有意义的。
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的位置?
答案 0 :(得分: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])
您将看到字符串"构造函数名为"只打印一次。
为了简单起见,我制作了一个字符串。你可以尝试使它成为ActorSystem的一个实例。