Scala play框架中@Singleton的使用

Posted

技术标签:

【中文标题】Scala play框架中@Singleton的使用【英文标题】:Use of @Singleton in Scala play framework 【发布时间】:2016-05-22 21:19:37 【问题描述】:

在定义 Scala 控制器时,将一个类标记为单例,使用 @Singleton 注释:

@Singleton
class Application

https://docs.oracle.com/javaee/7/api/javax/inject/Singleton.html 将单例定义为 '标识注入器仅实例化一次的类型。没有继承。那么Scala玩依赖注入框架依赖Java依赖注入吗?

来自https://www.playframework.com/documentation/2.5.x/ScalaDependencyInjection'Play 支持基于 JSR 330(在本页中描述)的运行时依赖注入和 Scala 中的编译时依赖注入。正在使用@Singleton,利用“基于 JSR 330 的依赖注入”,所以要使用“Scala 中的编译时依赖注入”需要什么?

【问题讨论】:

【参考方案1】:

是Scala玩依赖注入框架依赖Java 依赖注入?

是的,所以你需要写import javax.inject._每一个你使用DI的文件。

你需要做的基本上是

・ 定义接口为trait

trait FooService 
  def getBar(baz: String):Future[Bar]

・ 实现接口

class FooServiceImpl extends FooService 
  def getBar(baz: String) = ???

・ 通过 Module.scala(guice style) 绑定它们

class Module extends AbstractModule 
  override def configure() = 
    bind(classOf[FooService]).to(classOf[FooServiceImpl])
  

・使用它

class FooController @Inject()(fooService: FooService)(implicit exec: ExecutionContext) extends Controller 
  def index = Action.async = 
    fooService.getBar("fooBar").map_.doWhatEverYouWant
    .....
  

如您所见,使用这种DI方式时需要定义类参数。这就是为什么您不能使用Scala object而改用@Singleton的原因。

【讨论】:

所以不能声明对象参数而不是类参数来使用对象而不是类?编译时 DI 似乎比运行时更强大,使用运行时 DI 是否易于设置和配置? @blue-sky object parameter 是什么?无论如何。使用@singleton 而不是object 有点尴尬,尽管使用它并不需要太长时间。运行时 DI 具有更好的松耦合和可测试性,但类型更少。 那么可以使用 Scala 对象作为单例而不是单例注释吗?通过“对象参数”,我的意思是如果使用 Scala 对象(因此不使用单例注释)将“fooService:FooService”传递给 Scala 对象而不是 Scala 类【参考方案2】:

编译时和运行时 DI 之间的主要区别在于,使用运行时 DI,在运行应用程序之前,您不会知道您的依赖项是否会被连接和实现(即,您将收到运行时错误而不是编译时错误)

有关 play 的编译时 DI 支持的更多信息,我强烈建议您查看official documentation 的相关信息。

【讨论】:

以上是关于Scala play框架中@Singleton的使用的主要内容,如果未能解决你的问题,请参考以下文章

访问控制、Scala 中的权利、Play 框架

如何在视图页面中使用Play框架和Scala显示图像

将 bootstrap.css 文件链接到 Play 框架中的 scala.html 页面

play for scala 实现SessionFilter 过滤未登录用户跳转到登录页面

Scala下Play框架学习笔记(Actions,Controllers and Results)

在 Scala Play 框架 2.4 中使用两个资产目录