Where do I put startup code in Play Framework?
I want to run some code on startup to pre-cache some stuff, and would also like to start a Timer t开发者_StackOverflow中文版o re-cache some things outside the critical path of a web request. Is this possible with Play Framework, and where so I put this code?
You need to create a bootstrap job which will be executed by Play at application start time.
@OnApplicationStart
public class Bootstrap extends Job {
public void doJob() {
//do stuff
}
}
Read more about how to do this in the Play Manual.
For playframework 2.6+, please refer to playframework doc: Eager bindings
For playframework 2.0 to 2.5, use GlobalSettings, as the following code:
import play.*;
public class Global extends GlobalSettings {
@Override
public void onStart(Application app) {
Logger.info("Application has started");
}
@Override
public void onStop(Application app) {
Logger.info("Application shutdown...");
}
}
more information, go to playframework docs: JavaGlobal
In Play 2.4.+ you should use dependency injection with an (optional) lifecycle hook. Play will automatically use any class called Module
that is in the root package.
For example:
app/ApplicationStart.scala:
import scala.concurrent.Future
import javax.inject._
import play.api.inject.ApplicationLifecycle
// This creates an `ApplicationStart` object once at start-up and registers hook for shut-down.
@Singleton
class ApplicationStart @Inject() (lifecycle: ApplicationLifecycle) {
// Shut-down hook
lifecycle.addStopHook { () =>
Future.successful(())
}
//...
}
app/Module.scala:
import com.google.inject.AbstractModule
class Module extends AbstractModule {
override def configure() = {
bind(classOf[ApplicationStart]).asEagerSingleton()
}
}
More documentation of this pattern in Playframework docs.
Here's an example in an application.
Do not forget that the code shown in the above answers has to be in the base package of your app (no package specification). (I am running Play Framework 2.3.2).
Also, the code will not be run in dev mode until the first HTTP request is made!
In my case my code is this:
import play.*;
public class Global extends GlobalSettings {
@Override
public void onStart(Application app) {
String message = "Application has started! LOLADA";
Logger.info(message);
System.out.println(message);
}
@Override
public void onStop(Application app) {
String message = "Application shutdown...!!! LOLADA";
Logger.info(message);
System.out.println(message);
}
}
Located in the project structure as this:
(I am using IntelliJ IDEA).
As of Play Framework, version 2.7.1, in Java:
In /app/startup/Startup.java
:
package startup;
public class Startup {
public Startup() {
System.out.println("I ran on startup!");
}
}
In /app/startup/StartupBinder.java
:
package startup;
import com.google.inject.AbstractModule;
public class StartupBinder extends AbstractModule {
protected void configure() {
bind(Startup.class).asEagerSingleton();
}
}
Then add this to your /conf/application.conf
file:
play.modules.enabled += "startup.StartupBinder"
I need prepare some system properties for logger, but it seems logger is init before eager singletons. So I need do it in a customized application loader:
import play.api.ApplicationLoader
import play.api.inject.guice.{GuiceApplicationLoader, GuiceableModule}
class MyAppStartup extends GuiceApplicationLoader {
override protected def overrides(context: ApplicationLoader.Context): Seq[GuiceableModule] = {
// set system properties for logger configuration template
super.overrides(context)
}
}
add to application.conf
:
play.application.loader = MyAppStartup
reference:
https://www.playframework.com/documentation/2.6.x/ScalaCompileTimeDependencyInjection#application-entry-point
https://www.playframework.com/documentation/2.6.x/SettingsLogger#using-a-custom-application-loader
精彩评论