简体   繁体   English

playframework的全球范围在哪里以及它消失的好处是什么?

[英]Where was global scope in playframework and what are the benefits of it going away?

I am reading that the playframework is removing global state that is in older 2.4.x versions. 我正在读取playframework正在删除旧版2.4.x版本中的全局状态。

Can someone explain where the global state currently is and what are the benefits of removing global state? 有人可以解释目前全球状态在哪里以及消除全球状态有什么好处?

What is the global state? 什么是全球国家?

There is an object play.api.Play with the following field: 有一个对象play.api.Play与以下字段:

@volatile private[play] var _currentApp: Application = _

Where is it used? 在哪里使用?

Whenever you do Play.current you refer to that single mutable global field. 每当你做Play.current你都会引用那个单一的可变全局字段。 This is used all across the framework to access things such as: 这在整个框架中用于访问以下内容:

  • play.api.Play.configuration takes an implicit app play.api.Play.configuration采用隐式应用程序
  • play.api.libs.concurrent.Execution.defaultContext calls the internal context, which uses the currently running app to get the actor system play.api.libs.concurrent.Execution.defaultContext调用内部上下文,它使用当前运行的app来获取actor系统
  • play.api.libs.concurrent.Akka.system takes an implicit app play.api.libs.concurrent.Akka.system采用隐式应用程序
  • play.api.libs.ws.WS.url takes an implicit app play.api.libs.ws.WS.url采用隐式应用程序
  • and many more places.. 还有更多的地方..

Why is that bad? 为什么那么糟糕?

A number of functions just take an implicit app, so that's not really global state, right? 许多函数只是采用一个隐式应用程序,所以这不是真正的全局状态,对吧? I mean, you could just pass in that app. 我的意思是,你可以通过那个应用程序。 However where do you get it from? 但是你从哪里得到它? Typically, people would import play.api.Play.current . 通常,人们会导入play.api.Play.current

Another example: Let's say you want to develop a component that calls a webservice. 另一个例子:假设您要开发一个调用Web服务的组件。 What are the dependencies of such a class? 这类的依赖是什么? The WSClient . WSClient Now if you want to get an instance of that, you need to call play.api.libs.ws.WS.client and pass in an application. 现在,如果你想获得一个实例,你需要调用play.api.libs.ws.WS.client并传入一个应用程序。 So your pretty little component that logically only relies on a webservice client, now relies on the entire application. 因此,您在逻辑上仅依赖于Web服务客户端的漂亮小组件现在依赖于整个应用程序。

Another big factor and a direct consequence of the previous point is testing. 另一个重要因素和前一点的直接后果是测试。 Let's say you want to test your webservice component. 假设您要测试Web服务组件。 In theory, you'd only need to mock (or provide some dummy implementation of) the webservice client. 从理论上讲,您只需要模拟(或提供一些虚拟实现)Web服务客户端。 However now that somewhere in your code you're calling play.api.Play.current , you need to make sure that that field is set at the time it is called. 但是现在你的代码中的某个地方你正在调用play.api.Play.current ,你需要确保在调用它时设置该字段。 And the easiest way to ensure that is to start the play application. 确保这一点的最简单方法是启动播放应用程序。 So you're starting an entire application just to test your little component. 因此,您只是为了测试您的小组件而启动整个应用程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM