每个Web请求是否由Play控制器类的新实例处理,即控制器是否可以将状态存储在注入控制器构造函数的服务等字段中?(在文档中的什么地方说明了?)
据我所知,控制器默认是单例对象 。这没有明确记录,但暗示控制器实例已重用。请参阅Playframework
2.4的迁移指南:
注入的路由生成器还支持路由上的@运算符,但是它的含义略有不同(因为注入了所有内容),如果为控制器添加@前缀,而不是直接注入该控制器,则该控制器的JSR
330提供程序将被注射。例如,这可以用于消除循环依赖问题, 或者如果您希望每个请求实例化一个新操作 。
另外,请检查James
Roper(Play核心提交者)提出的有关控制器是否为单例的建议:
并非如此-如果使用Guice,则每次将控制器注入某个对象时,默认情况下都会创建一个新实例。也就是说,
路由器是单例,因此通过关联,它调用的控制器是单例 。但是,如果将控制器注入到其他位置,它将为该组件重新实例化。
这表明默认设置是在响应请求时重用控制器实例,如果要对每个请求执行新操作,则需要使用迁移指南中描述的语法。但是…由于我更倾向于证明和尝试事物而不是仅仅相信,所以我创建了一个简单的控制器来检查该语句:
package controllersimport play.api._import play.api.mvc._class Application extends Controller { def index = Action { println(this) Ok(views.html.index("Your new application is ready.")) }}对该操作执行多个请求将为所有发出的请求打印相同的对象 标识 。但是,如果我在路由上使用@运算符,则对于每个请求,我都会开始获得不同的 身份
。因此,是的, 默认情况下 , 控制器是(某种)单例 。
自从早期版本(如果是,是什么版本?)以来,Play框架是否发生了变化,有关控制器是有状态实例还是具有静态方法的无状态控制器?
默认情况下,Play始终提倡无状态控制器,如项目首页所示:
Play是基于轻量级, 无状态且 网络友好的体系结构。
并没有改变。因此,您不应使用控制器的字段/属性来保留随时间/请求而变化的数据。相反,只需使用控制器的字段/属性来引用同样也是无状态的其他组件/服务。
在哪里可以看到有关使用状态控制器时框架如何将服务注入控制器实例的代码示例,以及如何将服务注入静态控制器方法的示例代码?
关于代码示例,可以使用Activator模板存储库。下面是一些在控制器级别使用依赖注入的示例:
- https://github.com/adrianhurt/play-api-rest-seed
- https://github.com/knoldus/playing-reactive-mongo
- https://github.com/KyleU/boilerplay
不支持使用静态方法进行依赖注入,这就是为什么Playframework剧照提供了旧的api以用于静态方法的原因。经验法则是:在DI和静态方法之间进行选择。尝试同时使用两者只会给您的应用程序带来复杂性。



