4

Ich versuche zu spielen Framework zu lernen. Ich möchte die Lifecycle-Callbacks des Play-Frameworks in meiner Anwendung implementieren. Nun sah ich, dass es leicht Global mit getan werden kann unter:Wie implementiert man die Lifecycle-Callbacks von Spiel-Framework (2.5.x)

object Global extends GlobalSettings { 

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

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

} 

Aber es hat sich in der Spiel Rahmen (2.5.x) veraltet. Und sie bieten eifrige Bindung für onStart Rückrufe und für onStop und onError gibt es andere Mechanismen. Ich schaute in die Dokumentation der Version 2.5.x und sah einen Code wie folgt:

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

Aber leider konnte ich es nicht verstehen. Bei der Verwendung von GlobalSettings war es einfach, die Lebenszyklusrückrufe zu implementieren. Angenommen, ich werde nur eine Logger-Information in den Lebenszyklus-Callbacks implementieren. Keine komplexen Codes.
Wie kann ich dies für Start, Stop und Fehlerrückrufe in 2.5.x implementieren?

Antwort

4

Im Allgemeinen haben diese Mechanismen weg von der GlobalSettings Sache verschoben bedeutet auch, dass Sie solche "Rückrufe" nicht mehr global registrieren, aber Sie binden sie an eine Komponente/Klasse. Dies hat den Vorteil, dass die Initialisierung und das Herunterfahren einer bestimmten Komponente direkt in der jeweiligen Klasse stattfinden kann. Wenn Sie jedoch Code haben, der beim Starten (oder Herunterfahren) ausgeführt werden soll und nicht an eine bestimmte Komponente gebunden ist (z. B. Protokollierung, Startprüfungen usw.), müssen Sie neue Klassen für sie erstellen und sie in Ihrem Modul binden.

Beachten Sie, dass Sie im letzteren Fall die entsprechenden Klassen normalerweise als eifrige Singletons binden (um sicherzustellen, dass sie instanziiert werden), während im ersten Fall die Klassen als Teil des Abhängigkeitsbaums instanziiert werden.

Start: Ausführen von Code im Konstruktor jeder Klasse, die vom Dependency-Injektionscontainer verwaltet wird.

  1. Bind-Klasse im Modul
bind(classOf[Hello]).to(classOf[EnglishHello]).asEagerSingleton 
  1. Put Code in Konstruktor
class EnglishHello extends Hello { 
    println("hello") 
} 

Beachten Sie, dass die asEagerSingleton nicht per se erforderlich ist . Wie ich bin vorausgesetzt, Sie verwenden Führung als DI-Anbieter, können Sie sich hier, dass mehr über lesen: https://github.com/google/guice/wiki/Scopes

Shutdown: In jeder Klasse, die einige Shutdown-Code ausgeführt werden muss, einen Lebenszyklus-Callback registrieren. 1. Binden Klasse in Modul

bind(classOf[Hello]).to(classOf[EnglishHello]).asEagerSingleton 
  1. Register Lifecycle-Rückruf (und injizieren ApplicationLifecycle)
class EnglishHello @Inject() (lifecycle: ApplicationLifecycle) extends Hello { 
    lifecycle.addStopHook {() => 
    Future.successful(connection.stop()) 
    } 
} 

Beachten Sie, dass diese Klassen Umfang wollen als Singletons, da Sie sonst Stop-Hooks für jede Instanz registrieren - je nachdem, was Sie mit Hook stoppen, kann dies das sein, was Sie wollen.Lesen Sie mehr dazu hier: https://www.playframework.com/documentation/2.5.x/ScalaDependencyInjection#Stopping/cleaning-up

Fehler: Implementieren Sie Ihren eigenen HttpErrorHandler. Die Grundidee ist, dass Sie eine Klasse mit einer Reihe von Methoden implementieren, die von Play aufgerufen werden! zu den jeweiligen Fehlern. Dies ist hier dokumentiert: https://www.playframework.com/documentation/2.5.x/ScalaErrorHandling

+0

Ich verstehe diese Linie bind (classOf [Hallo]). Zu (classOf [EnglishHello]). AsEagerSingleton. Kannst du es im Detail erklären wie zB was die Hello-Klasse und warum zu verwenden ist (classOf [EnglishHello]) und was hier gemacht wird, indem du diese Zeile schreibst ?? Ich bin neu in diesem Rahmen. Kannst du es einfacher erklären? –

+0

Das bedeutet, wenn Sie eine Instanz von 'Hello' anfordern (zB.' Klasse Bye @Inject() (h: Hallo) {..} ') wird eine Instanz von' EnglishHello' injiziert (übergeben). Erfahren Sie mehr darüber, wie die Abhängigkeitsinjektion in diesem Vortrag von dem Schöpfer von guice nützlich sein kann: https://www.youtube.com/watch?v=0iSB0L9avmg – rethab

+0

Wie können Sie Unit-Klassen testen, die einen ApplicationLifecycle-Parameter verwenden? – Blankman