播放 2.4 添加模块而不是插件

Play 2.4 Adding Module instead of Plugin

我有一个 Play 2.3 应用程序,我正在迁移到 Play 2.4,我正在处理一个关于将插件迁移到模块的警告。我在此处关注此文档:

https://www.playframework.com/documentation/2.4.x/PluginsToModules

我现在在我的应用程序中有几个问题,其中有一些 Akka 演员。到目前为止,这是我对插件所做的:

  class MyPlugin extends Plugin {

    // I get the current Application
    val app = play.api.Play.current

    // On start of the plugin, I call my initializers
    def onStart: Unit = {
      super.onStart()
      doInitialize(app)
    }
  }

现在在我的 doInitialize 例程中,我对我需要的不同服务进行初始化。稍后我将这些服务公开为一个特征,并将这个特征混合在我需要服务引用的地方。例如,我的控制器看起来像:

object Application extends Controller with MyServices {

  ....
}

MyServices 在哪里

trait MyServices {

  def myActorRef: ActorRef
  ...
  ...
}

现在应该如何将此设置迁移到使用对整个应用程序影响很小的模块?当我从插件迁移到模块时,我也不清楚我应该把我的 onStart 方法内容放在哪里!

编辑:我尝试了以下方法:

sealed trait MyComp
class MyCompImpl @Inject() (lifecycle: ApplicationLifecycle) extends MyComp {
  val application = MyConfig(play.api.Play.current)

  // initialize upon start
  Initializer.doInitialize(application)

  // destroy upon stop
  lifecycle.addStopHook(() => {
    Future.successful { Initializer.destroyConfig(application) }
  })
}

我的模块定义如下:

class MyModule extends Module {

  override def bindings(environment: play.api.Environment, configuration: Configuration): Seq[Binding[_]] = {
    logger.info(s"registering bindings")
    Seq(
      bind[MyComp].to[MyCompImpl].eagerly()
    )
  }
}

现在失败了,原因是:

CreationException:无法创建注入器,请参阅以下错误:

1) Error injecting constructor, java.lang.RuntimeException: There is no started application
  at com.config.MyCompImpl.<init>(MyModule.scala:25)
  while locating com.config.MyCompImpl

每次将 Play 应用程序升级到较新版本都成为 *** 的痛点!

您需要考虑 2.4 中的另一项更改:“Removing GlobalSettings”:

Anything that needs to happen on start up should now be happening in the constructor of a dependency injected class. A class will perform its initialisation when the dependency injection framework loads it. If you need eager initialisation (because you need to execute some code before the application is actually started), define an eager binding.

在此页面 - https://www.playframework.com/documentation/2.4.x/PluginsToModules - 你有:

bind[MyComponent].to[MyComponentImpl]

在你的例子中你需要使用

bind[MyComponent].to[MyComponentImpl].asEagerSingleton

并且代码 doInitialize(app) 必须是 运行 在 MyComponentImpl 的构造函数中 like

class MyComponentImpl extends MyComponent {
  initialize() 
  def initialize() = {
     //initialize your app
  }
}

我设法解决了这个问题,如下所示:

sealed trait MyComp
class MyCompImpl @Inject() (app: Application, lifecycle: ApplicationLifecycle) extends MyComp {
  val application = Myconfig(app)

  // initialize upon start
  Initializer.doInitialize(application)

  // destroy upon stop
  lifecycle.addStopHook(() => {
    Future.successful { Initializer.destroyConfig(application) }
  })
}