如何实现play框架的生命周期回调(2.5.x)

时间:2016-06-01 03:11:01

标签: scala playframework application-lifecycle playframework-2.5

我正在努力学习游戏框架。我想在我的应用程序中实现play框架的生命周期回调。现在我看到可以使用下面的 GlobalSettings 轻松完成:

object Global extends GlobalSettings {

  override def onStart(app: Application) {
    Logger.info("Application has started")
  }  

  override def onStop(app: Application) {
    Logger.info("Application shutdown...")
  }  

}

但它已在播放框架(2.5.x)中弃用。他们正在为onStart回调提供热切的约束,而onStoponError还有其他机制。我查看了2.5.x版的文档,并在下面看到了一个代码:

import com.google.inject.AbstractModule
import com.google.inject.name.Names

class Module extends AbstractModule {
  def configure() = {

    bind(classOf[Hello])
      .annotatedWith(Names.named("en"))
      .to(classOf[EnglishHello]).asEagerSingleton

    bind(classOf[Hello])
      .annotatedWith(Names.named("de"))
      .to(classOf[GermanHello]).asEagerSingleton
  }
}

但不幸的是我无法理解它。使用GlobalSettings时,很容易实现生命周期回调。假设我将在生命周期回调中实现Logger信息。没有复杂的代码。
如何在 2.5.x 中实现启动,停止和错误回调?

1 个答案:

答案 0 :(得分:8)

一般情况下,将这些机制从GlobalSettings移开也意味着您不再注册此类回调'全局,但您将它们绑定到组件/类。这提供了以下益处:特定组件的初始化和关闭可以直接在相应类中发生。但是,如果您希望在启动(或关闭)时运行的代码与特定组件无关(例如,日志记录,启动检查等),则必须为它们创建新类并将它们绑定到您的模块中。

请注意,在后一种情况下,您通常将各个类绑定为急切的单例(以确保它们被实例化),而在前一种情况下,类被实例化为依赖树的一部分。

启动:在依赖注入容器管理的任何类的构造函数中运行代码。

  1. 在模块中绑定类

    bind(classOf[Hello]).to(classOf[EnglishHello]).asEagerSingleton
    
  2. 将代码放在构造函数

    class EnglishHello extends Hello {
      println("hello")
    }
    
  3. 请注意,asEagerSingleton本身并不是必需的。由于我假设您使用Guice作为DI提供商,您可以在此处详细了解:https://github.com/google/guice/wiki/Scopes

    关闭:在任何需要运行某些关闭代码的类中,注册一个生命周期回调。

    1. 在模块中绑定类

      bind(classOf[Hello]).to(classOf[EnglishHello]).asEagerSingleton
      
    2. 注册生命周期回调(并注入ApplicationLifecycle

      class EnglishHello @Inject() (lifecycle: ApplicationLifecycle) extends Hello {
        lifecycle.addStopHook { () =>
          Future.successful(connection.stop())
        }
      }
      
    3. 请注意,您可能希望将这些类的范围限定为单例,否则您最终会为每个实例注册停止挂钩 - 这取决于您的挂钩的作用,这可能就是您想要的。在此处详细了解:https://www.playframework.com/documentation/2.5.x/ScalaDependencyInjection#Stopping/cleaning-up

      错误:实施您自己的HttpErrorHandler。基本思想是你实现一个包含许多方法的类,这些方法将由Play调用!关于各自的错误。这在此处记录:https://www.playframework.com/documentation/2.5.x/ScalaErrorHandling