我需要在应用程序启动时安排一个重复任务,任务本身非常简单,只需向应用程序发送一个即发即弃的HTTP调用。我不是游戏专家,我会认为直截了当的解决方案就像在Global.onStart
中使用Global
一样。从Play 2.4开始,GuiceApplicationLoader
配置在某种程度上被弃用,有利于新的Guice DI。抄袭DI documentation的建议我无法为这个问题找到一个很好的解决方案。我设法得到的最好的是在BuiltInComponentsFromContext
之上编写一个包装器,调用WSClient
的自定义实现,但在这种情况下,我无法使用注入来获取object Global extends GlobalSettings {
override def onStart(app: Application) = {
Akka.system.schedule(2.hours, 2.hours, theTask)
}
}
。使用Play 2.4重写类似内容的最佳方法是什么:
{{1}}
答案 0 :(得分:7)
更新:现在可以更好地记录Play 2.6:https://www.playframework.com/documentation/2.6.x/ScheduledTasks
您可以通过创建这样的模块来解决这个问题(注意代码注释):
package tasks
import javax.inject.{Singleton, Inject}
import akka.actor.ActorSystem
import com.google.inject.AbstractModule
import play.api.inject.ApplicationLifecycle
// Using the default ExecutionContext, but you can configure
// your own as described here:
// https://www.playframework.com/documentation/2.4.x/ThreadPools
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import scala.concurrent.Future
import scala.concurrent.duration._
class MyRecurrentTaskModule extends AbstractModule {
override def configure() = {
// binding the RecurrentTask as a eager singleton will force
// its initialization even if RecurrentTask is not injected in
// any other object. In other words, it will starts with when
// your application starts.
bind(classOf[RecurrentTask]).asEagerSingleton()
}
}
@Singleton
class RecurrentTask @Inject() (actorSystem: ActorSystem, lifecycle: ApplicationLifecycle) {
// Just scheduling your task using the injected ActorSystem
actorSystem.scheduler.schedule(1.second, 1.second) {
println("I'm running...")
}
// This is necessary to avoid thread leaks, specially if you are
// using a custom ExecutionContext
lifecycle.addStopHook{ () =>
Future.successful(actorSystem.shutdown())
}
}
之后,您必须启用此模块,在conf/application.conf
文件中添加以下行:
play.modules.enabled += "tasks.MyRecurrentTaskModule"
然后,只需启动应用程序,向其发出请求,并查看计划任务将每秒运行一次。
<强>参考强>: