Playframework 为什么在play 2.5中使用单例控制器?

Playframework 为什么在play 2.5中使用单例控制器?,playframework,controller,Playframework,Controller,我才刚开始,我想我不太明白。据我所知,在路由器创建的那一刻,所有控制器都作为依赖项创建。然后它们继续生存,直到应用程序终止时路由器死亡。如果这种情况下,将它们声明为单例似乎是多余的。如果您有一个由路由器实例化的控制器(即默认值),那么它们是隐式单例的,因为路由器只存在一次。但是,如果您将控制器注入其他地方,您仍然会得到一个新实例,除非它被标记为singleton 来源:为了摆脱全局状态(这与无状态设计的想法背道而驰),Play引入了DI(我想大概是v2.4),在v2.5中,它现在默认使用注入路由

我才刚开始,我想我不太明白。据我所知,在路由器创建的那一刻,所有控制器都作为依赖项创建。然后它们继续生存,直到应用程序终止时路由器死亡。如果这种情况下,将它们声明为单例似乎是多余的。

如果您有一个由路由器实例化的控制器(即默认值),那么它们是隐式单例的,因为路由器只存在一次。但是,如果您将控制器注入其他地方,您仍然会得到一个新实例,除非它被标记为singleton


来源:

为了摆脱全局状态(这与无状态设计的想法背道而驰),Play引入了DI(我想大概是v2.4),在v2.5中,它现在默认使用注入路由器。GoogleGuice是Play打包的默认DI框架(您可以使用其他框架,但Guice是默认框架)

现在(通常)Guice认为创建控制器的新实例比使用单例更快,而且线程更安全—请参阅

如果要将控制器的实例限制为仅1,则可以将其标记为单实例,但必须将其标记为单实例,因为它将在线程之间共享

我认为Activator模板可能需要更多的文档来解释为什么它们似乎在不需要时生成
@Singleton
控制器,因为这很混乱<例如,code>HomeController(在播放Scala seed时)被混淆地声明为
@Singleton
,但它没有任何理由

一般来说,最好不要使用
@Singleton
,除非您对不变性和线程安全有了合理的理解。如果您认为您有单例的用例,那么只需确保您正在保护任何共享状态


简言之,不要使用
@Singleton

你能给我一个例子,说明你什么时候会在别处注入控制器吗?不,我认为这是一个糟糕的做法。如果您想要共享功能,您应该创建一个业务服务或其他帮助器类。我认为在别处注入一个控制器是一个相当技术性的问题,因为这些控制器并不是真正的单例。你不必把它们声明为单例。你在哪里读到的?哪里也没有。但是,如果你看一看随播放安装而来的控制器,它们都被注释为SingleTonSah,我看到了,我在下面放了一个更大的注释-它是关于无状态的。控制器过去是播放框架中的对象,然后DI出现:)所以最好的做法是将每个控制器声明为@Singleton?我想我还是有点困惑。我仍然可以看到anu时间里会创建更多的实例。因此,单例符号似乎仍然是多余的。此外,我的印象是,所有请求都由同一个线程处理,因此无论是无状态的还是无状态的,都没有关系not@user25470每个请求1个线程,否则您的所有请求都必须排队等待轮到1个线程,这意味着您的应用程序非常慢。您可能已经在文档中读到操作是非阻塞的-这意味着您不应该在控制器操作中执行任何可能导致其进行上下文切换(例如I/O)的操作-这是因为用于播放的默认线程池是主机上每个核心1个线程。因此,线程被分配一个请求,快速执行操作(非阻塞),并快速返回到池中处理下一个请求。