【发布时间】:2011-02-05 15:12:03
【问题描述】:
我想在启动时运行一些代码来预缓存一些东西,并且还想启动一个 Timer 来重新缓存 Web 请求关键路径之外的一些东西。 Play Framework 可以做到这一点吗?我把这段代码放在哪里?
【问题讨论】:
标签: playframework
我想在启动时运行一些代码来预缓存一些东西,并且还想启动一个 Timer 来重新缓存 Web 请求关键路径之外的一些东西。 Play Framework 可以做到这一点吗?我把这段代码放在哪里?
【问题讨论】:
标签: playframework
您需要创建一个引导作业,该作业将在应用程序启动时由 Play 执行。
@OnApplicationStart
public class Bootstrap extends Job {
public void doJob() {
//do stuff
}
}
在Play Manual 中了解有关如何执行此操作的更多信息。
【讨论】:
playframework 2.6+请参考playframework doc: Eager bindings
playframework 2.0 到 2.5,使用 GlobalSettings,如下代码:
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...");
}
}
【讨论】:
在 Play 2.4.+ 中,您应该使用带有(可选)生命周期钩子的依赖注入。 Play 将自动使用根包中名为 Module 的任何类。
例如:
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()
}
}
Playframework docs 中有关此模式的更多文档。
这是一个示例in an application。
【讨论】:
不要忘记上述答案中显示的代码必须在您应用的基础包中(无包规范)。 (我正在运行 Play Framework 2.3.2)。
另外,在发出第一个 HTTP 请求之前,代码不会在开发模式下运行!
就我而言,我的代码是这样的:
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);
}
}
在项目结构中的位置如下:
(我正在使用 IntelliJ IDEA)。
【讨论】:
Play Framework 版本 2.7.1,Java 版本:
在/app/startup/Startup.java:
package startup;
public class Startup {
public Startup() {
System.out.println("I ran on startup!");
}
}
在/app/startup/StartupBinder.java:
package startup;
import com.google.inject.AbstractModule;
public class StartupBinder extends AbstractModule {
protected void configure() {
bind(Startup.class).asEagerSingleton();
}
}
然后将其添加到您的 /conf/application.conf 文件中:
play.modules.enabled += "startup.StartupBinder"
【讨论】:
我需要为记录器准备一些系统属性,但似乎记录器在急切的单例之前是初始化的。所以我需要在自定义的应用程序加载器中完成:
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)
}
}
添加到application.conf:
play.application.loader = MyAppStartup
参考:
【讨论】: