如何使用模块而不是插件插入播放生命周期?
Posted
技术标签:
【中文标题】如何使用模块而不是插件插入播放生命周期?【英文标题】:How to plug into the play lifecycle with a module instead of a Plugin? 【发布时间】:2015-07-25 05:36:58 【问题描述】:我看到 Plugin 类现在已被弃用(从 2.4.x 版本的 play 开始)......在 api 文档中它说我应该使用模块......所以这是我的问题。 如何编写模块,以及如何将该模块插入主应用的播放生命周期?
【问题讨论】:
【参考方案1】:您没有指定您使用的是哪种语言,因此我将快速介绍这两种语言。我将两个答案都基于以下存储库:
https://github.com/schaloner/deadbolt-2-java https://github.com/schaloner/deadbolt-2-scalaJava
以您想要的任何方式编写您的功能 - 没有要扩展的特定类。如果你对 Play 组件有依赖,例如 Configuration
,你应该注入它们。
@Singleton
public class MyModuleCode
private final boolean enableWidgets;
@javax.inject.Inject
public MyModuleCode(final Configuration configuration)
this.enableWidgets = configuration.getBoolean("widgets.enabled", false);
请注意,使用依赖注入代替静态引用。另外,请注意我给这个例子一个 @Singleton
注释,但也可以有,例如,每个请求的范围。
更多信息请见the Play DI docs
公开模块的组件。为此,请扩展 play.api.inject.Module
类并实现 public Seq<Binding<?>> bindings(final Environment environment, final Configuration configuration)
。
package com.example.module;
public class MyModule extends Module
@Override
public Seq<Binding<?>> bindings(final Environment environment,
final Configuration configuration)
return seq(bind(MyModuleCode.class).toSelf().in(Singleton.class));
在这里,你还可以将实现绑定到接口,配置实例提供者等等。
如果您要公开发布该模块,假设您在此处执行此操作 - 这超出了问题的范围。我们还假设您已经为正在处理的任何项目中的模块添加了依赖项。
启用application.conf
中的模块。
play
modules
enabled += com.example.module.MyModule
通过您的模块公开的组件(在此示例中为 MyModuleCode
)现在可用于注入到您的控制器、操作等中。
如果需要关闭钩子,只需将ApplicationLifecycle
注入组件并注册钩子即可;详情请见https://playframework.com/documentation/2.4.x/JavaDependencyInjection#Stopping/cleaning-up。
斯卡拉
以您想要的任何方式编写您的功能 - 没有要扩展的特定类。如果你对 Play 组件有依赖,例如 CacheApi
,你应该注入它们。
@Singleton
class DefaultPatternCache @Inject() (cache: CacheApi) extends PatternCache
override def apply(value: String): Option[Pattern] = cache.getOrElse[Option[Pattern]](key = s"Deadbolt.pattern.$value") Some(Pattern.compile(value))
请注意,使用依赖注入代替静态引用。另外,请注意我给这个例子一个 @Singleton
注释,但也可以有,例如,每个请求的范围。
更多信息请见the Play DI docs
公开模块的组件。为此,请扩展 play.api.inject.Module
类并实现 def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]]
。
package com.example.module
import com.example.module.cache.DefaultPatternCache, PatternCache
import play.api.inject.Binding, Module
import play.api.Configuration, Environment
class MyModule extends Module
override def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = Seq(bind[PatternCache].to[DefaultPatternCache])
在这里,您还可以将实现绑定到特征、配置实例提供程序等。
如果您要公开发布该模块,假设您在此处执行此操作 - 这超出了问题的范围。我们还假设您已经为正在处理的任何项目中的模块添加了依赖项。
启用application.conf
中的模块。
play
modules
enabled += com.example.module.MyModule
通过您的模块公开的组件(在此示例中为 MyModuleCode
)现在可用于注入到您的控制器、操作等中。
如果需要关闭钩子,只需将ApplicationLifecycle
注入组件并注册钩子即可;详情请见https://playframework.com/documentation/2.4.x/ScalaDependencyInjection#Stopping/cleaning-up。
总结
模块不再是什么特别的东西——它们只是对可注入组件进行分组的一种方式。
【讨论】:
如果我想注册一个 Jackson json 模块怎么办?我应该在哪里这样做(没有全局设置)?我不需要在我的代码中注入某个类的一些实例,我只需要在任何 http 请求之前运行一些代码。 文档中有明确的介绍:playframework.com/documentation/2.4.x/JavaHttpRequestHandlersplayframework.com/documentation/2.4.x/ScalaHttpRequestHandlers 我的意思是,我需要在任何 http 请求发生之前执行此操作,但只有一次,而不是一个 pero 请求。 将包含代码的类声明为一个急切的单例——它会在应用程序启动时运行一次。详情请见playframework.com/documentation/2.4.x/…。以上是关于如何使用模块而不是插件插入播放生命周期?的主要内容,如果未能解决你的问题,请参考以下文章