§编写 Play 模块
注意:此页面涵盖了用于向 Play 添加功能的新 模块系统。
从 2.5.x 版本开始,已弃用的
play.api.Plugin
系统已移除。
可以使用任何依赖注入框架编写 模块。但是,当您想要扩展 Play 时,您需要避免对特定框架的依赖,以便您的扩展可以独立于依赖注入工作。Play 以前使用 play.api.Plugin
系统来实现此目的,但在 2.5.x 版本中,插件已被 Play 模块取代。
Play 模块是一个扩展 play.api.inject.Module
的类,可以注册到 Play,而无需明确依赖特定的依赖注入框架。这允许每个人使用 Play 模块。
Play 模块列表可在 模块目录 中找到。
此外,由于 Play 使用 Play 模块来实现内置功能,因此必须使用 Play 模块来替换或增强内置功能。
§创建和迁移 Play 模块
创建 Play 模块很简单
class MyCode {
// add functionality here
}
class MyModule extends play.api.inject.Module {
def bindings(environment: Environment, configuration: Configuration): Seq[play.api.inject.Binding[_]] = {
Seq(bind[MyCode].toInstance(new MyCode))
}
}
有关更多信息,请参阅 插件到模块 的“创建模块类”部分。
§模块注册
默认情况下,Play 将加载在根包(“app”目录)中定义的任何名为 Module
的类,或者
您可以在 reference.conf
或 application.conf
中显式定义它们
play.modules.enabled += "modules.MyModule"
§应用程序生命周期
模块可以通过将 play.api.inject.ApplicationLifecycle
特性注入到单例实例并添加一个关闭挂钩来检测 Play 关闭事件。
有关更多详细信息,请参阅 `ApplicationLifecycle` 示例 和 ApplicationLifecycle 参考。
§测试 Play 模块
可以使用 Play 的内置测试功能来测试模块,使用 GuiceApplicationBuilder
并向模块添加绑定。
val application = new GuiceApplicationBuilder()
.bindings(new MyModule)
.build()
val myCode = application.injector.instanceOf(classOf[MyCode])
myCode must beAnInstanceOf[MyCode]
有关更多详细信息,请参阅 使用 Guice 进行测试。
§列出现有 Play 模块
该 Modules.locate(env, conf)
方法将显示应用程序中所有可用 Play 模块的列表。
§覆盖内置模块
在某些情况下,Play 提供了一个必须覆盖的内置模块。
例如,消息 功能由 MessagesApi 特性 实现,并由 DefaultMessagesApi 支持。如果您编写一个扩展 MessagesApi
的替换类 MyMessagesApi
,您可以使用以下方法绑定它:
class MyI18nModule extends play.api.inject.Module {
def bindings(environment: Environment, configuration: Configuration): Seq[play.api.inject.Binding[_]] = {
Seq(
bind[Langs].toProvider[DefaultLangsProvider],
bind[MessagesApi].toProvider[MyMessagesApiProvider]
)
}
}
§测试覆盖
应用程序的测试应使用 overrides
方法来替换现有实现
val application = new GuiceApplicationBuilder()
.overrides(new MyI18nModule)
.build()
§注册覆盖
由于 I18nModule
在 reference.conf
中自动加载,因此您必须首先 禁用 默认模块,然后才能添加替换模块
play.modules.disabled += "play.api.i18n.I18nModule"
play.modules.enabled += "modules.MyI18nModule"
在发布 Play 模块时,您不应在 reference.conf
中禁用现有模块,因为这可能会导致意外后果。有关详细信息,请参阅 迁移页面。
下一步:从插件 API 迁移
在此文档中发现错误?此页面的源代码可以在 此处 找到。在阅读 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?转到 我们的社区论坛 与社区开始对话。