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

时间:2015-10-18 08:30:57

标签: playframework dependency-injection module

我有一个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
  ...
  ...
}

现在应该如何将此设置迁移到使用对整个应用程序影响不大的模块?当我从Plugin迁移到Module时,我还不清楚我应该把我的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 个答案:

答案 0 :(得分:1)

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

  

现在应该发生任何需要在启动时发生的事情   依赖注入类的构造函数。一堂课将表演   它的初始化时依赖注入框架加载它。   如果你需要急切的初始化(因为你需要执行一些   实际启动应用程序之前的代码),定义一个渴望   结合。

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

bind[MyComponent].to[MyComponentImpl]

在您的示例中,您需要使用

bind[MyComponent].to[MyComponentImpl].asEagerSingleton

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

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

答案 1 :(得分:0)

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

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) }
  })
}