Where do I put startup code in Play Framework?

2019-04-17 18:48发布

I want to run some code on startup to pre-cache some stuff, and would also like to start a Timer to 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?

5条回答
祖国的老花朵
2楼-- · 2019-04-17 19:28

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.

查看更多
看我几分像从前
3楼-- · 2019-04-17 19:30

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:

查看更多
男人必须洒脱
4楼-- · 2019-04-17 19:32

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:

project structure

(I am using IntelliJ IDEA).

查看更多
smile是对你的礼貌
5楼-- · 2019-04-17 19:36

In playframework 2.0 and above, 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

查看更多
狗以群分
6楼-- · 2019-04-17 19:44

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.

查看更多
登录 后发表回答