我刚刚开始,我不认为我理解得很好。据我所知,所有控制器都是在创建路由器时创建的依赖项。然后它们继续运行,直到应用程序终止时路由器终止。如果是这种情况,宣称它们似乎是多余的单身。
答案 0 :(得分:11)
摆脱全局状态(违背无状态设计的想法)播放引入DI(我认为在v2.4左右)和v2.5中它现在默认使用注入路由器。 Google Guice是Play打包的默认DI框架(您可以使用其他框架,但Guice是默认设置)。
现在(一般而言)Guice认为创建Controller的新实例比使用单例更快,更安全 - 请参阅Guice docs for more。
如果您have a need将控制器的实例限制为1,那么您可以将其标记为单例,但必须将其设为Thread-safe,因为它将在线程之间共享。
我认为Activator模板可以使用更多的文档来解释为什么它们似乎在它们似乎不需要时会生成@Singleton
控制器,因为它令人困惑。 HomeController
(在Play-Scala种子中)例如,当它没有任何案例时,会混淆地声明@Singleton
。
一般情况下,除非您对不变性和线程安全有一个公平的理解,否则最好不要使用@Singleton
。如果你认为你有一个Singleton的用例,只是确保你保护任何共享状态。
简而言之,请勿使用@Singleton
。
答案 1 :(得分:2)
如果你有一个由路由器实例化的控制器(即默认值),那么它们是隐式单例,因为路由器只存在一次。但是,如果将控制器注入其他位置,除非将其标记为单例,否则仍会获得新实例。
来源:https://github.com/playframework/playframework/issues/4508#issuecomment-127820190