【问题标题】:Creating a singleton object without an interface via Play Framework通过 Play 框架创建没有接口的单例对象
【发布时间】:2016-12-01 01:29:58
【问题描述】:

我刚刚从我的学长那里听说,如果我在该具体类上添加了@Singleton 注释并且它可以在系统中无缝工作,但我无法在不使用依赖注入中的接口的情况下将具体类实例化为 Singleton。但这样做,反而会创建多个类实例,他提到。

顺便说一下,我正在使用带有 Guice DI 的 Play Scala 框架。

我尝试用谷歌搜索验证是否属实,但找不到答案。

谁能给我一个具体的解释?在java中我可以创建一个没有接口的单例类。

【问题讨论】:

  • 我对 scala 不太了解,但你绝对可以将实例类绑定为单例,例如:java 中的 bind(MyImpl.class).in(Singleton.class)。由于 java 和 scala 可以很好地协同工作(我假设 guice 是 java 框架的 scala 采用),这似乎不太可能?不过,您可以自己为此编写一个非常快速的测试

标签: scala playframework dependency-injection guice


【解决方案1】:

如果您的意思是是否可以在没有“同伴”训练和绑定特征到模块中的实现的情况下立即注入一个类,那么它是可能的。 我刚刚实验过。这是我的简单课程: 打包服务

import javax.inject.Singleton

/**
  * Created by Alex on 7/27/2016.
  */
@Singleton
class JustASingleton {
  def giveMeFive = "5"
}

然后在我的控制器中,我将它注入没有任何特征(你称之为接口):

class MainController @Inject()(
                                environment:play.api.Environment,
                                documentService:DocumentService,
                                userService:UserService,
                                singletonInstance:JustASingleton
                              )(implicit ec:ExecutionContext)extends Controller {


  def testSingletonInjection() = Action(Ok(singletonInstance.giveMeFive))
  ...

然后在路线中我有这条线:

GET     /singleton                  controllers.MainController.testSingletonInjection

它编译正常,当我转到 localhost:9000/singleton 时,我得到了正确的 html 响应。因此,没有特征的注入并将实现绑定到特征确实有效。

【讨论】:

  • 感谢您的回答。是的,你的样本确实有效。我想知道 JustASingleton 类是否真的只创建一个实例对象。
  • 好吧,这个注解的 javadoc 说 Identifies a type that the injector only instantiates once.。我不能说 100% 肯定我可以保证,也不能可靠地测试这一点,但通常我倾向于相信文档所说的:)
  • 我对您的示例评论进行了轻微更改的测试,我可以得出结论,实例确实是单例的。
【解决方案2】:

为了记录,我会发布我的答案。

我试图扩展@AlexanderArendar 的实验:

import javax.inject.Singleton

/**
  * Created by Alex on 7/27/2016.
  */
@Singleton
class JustASingleton {
  def giveMeFive = "5"
}

第一个控制器

class MainController @Inject()(
                                environment:play.api.Environment,
                                documentService:DocumentService,
                                userService:UserService,
                                singletonInstance:JustASingleton
                              )(implicit ec:ExecutionContext)extends Controller {


  def testSingletonInjection() = Action(Ok("controller id " + System.identityHashCode(this).toString + " and Injected Bean id " + System.identityHashCode(singletonInstance).toString))
  ...

第二控制器

class SecondController @Inject()(
                                    environment:play.api.Environment,
                                    documentService:DocumentService,
                                    userService:UserService,
                                    singletonInstance:JustASingleton
                                  )(implicit ec:ExecutionContext)extends Controller {
    
    
      def testSingletonInjection() = Action(Ok("controller id " + System.identityHashCode(this).toString + " and Injected Bean id " + System.identityHashCode(singletonInstance).toString))
      ...

然后在路线中

GET     /singletonX                  controllers.MainController.testSingletonInjection

GET     /singletonY                  controllers.SecondController.testSingletonInjection

调用这两个端点给了我以下结果:

controller id 1944357758 和 Injected Bean id 853668078

controller id 943948501 和 Injected Bean id 853668078

我可以根据测试得出结论,可以将具体类创建为单例,而无需提供接口

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-16
    • 1970-01-01
    • 1970-01-01
    • 2015-11-09
    • 2012-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多