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

Bla*_*man 5 scala playframework

我正在读取playframework正在删除旧版2.4.x版本中的全局状态.

有人可以解释目前全球状态在哪里以及消除全球状态有什么好处?

ret*_*hab 1

什么是全球状态?

有一个play.api.Play具有以下字段的对象:

@volatile private[play] var _currentApp: Application = _
Run Code Online (Sandbox Code Playgroud)

它用在哪里?

每当您这样做时,Play.current您都会引用该单个可变全局字段。整个框架都使用它来访问以下内容:

  • play.api.Play.configuration采用隐式应用程序
  • play.api.libs.concurrent.Execution.defaultContext调用内部上下文,它使用当前运行的应用程序来获取 Actor 系统
  • play.api.libs.concurrent.Akka.system采用隐式应用程序
  • play.api.libs.ws.WS.url采用隐式应用程序
  • 还有更多的地方..

为什么这么糟糕?

许多函数只需要一个隐式应用程序,所以这不是真正的全局状态,对吧?我的意思是,你可以直接传递那个应用程序。然而你从哪里得到它呢?通常,人们会导入play.api.Play.current.

另一个例子:假设您想要开发一个调用 Web 服务的组件。这样的类有哪些依赖关系呢?这WSClient。现在,如果您想获取它的实例,您需要调用play.api.libs.ws.WS.client并传入一个应用程序。因此,逻辑上仅依赖于 Web 服务客户端的漂亮小组件现在依赖于整个应用程序。

另一个重要因素和上一点的直接后果是测试。假设您想要测试您的 Web 服务组件。理论上,您只需要模拟(或提供一些虚拟实现)Web 服务客户端。然而,现在您正在调用的代码中的某个位置play.api.Play.current,您需要确保在调用该字段时设置该字段。确保这一点的最简单方法是启动播放应用程序。因此,您启动整个应用程序只是为了测试您的小组件。