如何使用模块而不是插件插入播放生命周期?

How to plug into the play lifecycle with a module instead of a Plugin?

我看到插件 class 现已弃用(从 2.4.x 版本开始)...在 api 文档中它说我应该改用模块。 .. 所以这是我的问题。 如何编写模块,以及如何将该模块插入主应用程序的播放生命周期?

您没有指定您使用的是哪种语言,所以我会很快介绍这两种语言。我将这两个答案都基于以下存储库:

Java

  1. 以您想要的任何方式编写您的功能 - 没有特定的 classes 可以扩展。如果你对 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

  1. 公开模块的组件。为此,扩展 play.api.inject.Module class 并实施 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));
        }
    }
    

在这里,您还可以将实现绑定到接口,配置实例提供者等。

  1. 如果您要公开发布该模块,我们假设您在此处执行此操作 - 这超出了问题的范围。我们还假设您已经在您正在处理的任何项目中为模块添加了依赖项。

  2. 启用application.conf中的模块。

    play {
        modules {
            enabled += com.example.module.MyModule
        }
    }
    
  3. 通过您的模块公开的组件 - 在本例中只是 MyModuleCode - 现在可用于注入您的控制器、操作等。

  4. 如果需要关闭钩子,只需在组件中注入ApplicationLifecycle并注册钩子即可;有关详细信息,请参阅 https://playframework.com/documentation/2.4.x/JavaDependencyInjection#Stopping/cleaning-up

斯卡拉

  1. 以您想要的任何方式编写您的功能 - 没有特定的 classes 可以扩展。如果你对 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

  1. 公开模块的组件。为此,扩展 play.api.inject.Module class 并实施 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])
    }
    

在这里,您还可以将实现绑定到特征,配置实例提供者等。

  1. 如果您要公开发布该模块,我们假设您在此处执行此操作 - 这超出了问题的范围。我们还假设您已经在您正在处理的任何项目中为模块添加了依赖项。

  2. 启用application.conf中的模块。

    play {
        modules {
            enabled += com.example.module.MyModule
        }
    }
    
  3. 通过您的模块公开的组件 - 在本例中只是 MyModuleCode - 现在可用于注入您的控制器、操作等。

  4. 如果需要关闭钩子,只需在组件中注入ApplicationLifecycle并注册钩子即可;有关详细信息,请参阅 https://playframework.com/documentation/2.4.x/ScalaDependencyInjection#Stopping/cleaning-up

总结

模块不再有任何特殊之处 - 它们只是一种对可注入组件进行分组的方式。