[英]How do I perform an action on server startup in the Scala Play Framework?
我的conf/
目录中有一个配置文件servers.conf
,只要路由/servers
被命中,我的ServerController就会读取它。 这不具备性能,因为当文件不会更改时,它需要在每次连续命中时重新读取配置文件。 此外,如果配置文件有问题,我可以尽快告诉用户,而不是在页面命中时抛出异常。
目前我在ServerController.scala
有这个:
case class Server(ip: String, port: String)
/**
* This controller creates an `Action` to handle HTTP requests to the
* application's server page.
*/
@Singleton
class ServerController @Inject() extends Controller {
/**
* Create an Action to render an HTML page with a the list of servers.
* The configuration in the `routes` file means that this method
* will be called when the application receives a `GET` request with
* a path of `/servers`.
*/
def index = Action {
val serverList = ConfigFactory.load().getConfigList("servers")
val servers: List[Server] = serverList match {
case null => Nil
case _ => serverList map { s =>
Server(s.getString("ip"), s.getString("port"))
} filter { s =>
s.ip != null && s.port != null
}.toList
}
Ok(views.html.servers(servers))
}
}
我的目标是让服务器在启动时读取配置文件,并在路由被命中时将服务器列表传递给ServerController,如果在配置文件中读取没有问题。 如果有问题,我希望立即抛出异常。
我似乎无法找到我的应用程序的入口点,所以我不知道如何在启动时执行操作。
有谁知道如何做到这一点? 我正在使用Play 2.5.x.
如果您使用的是最新版本的Play,它会在启动时查找根软件包中名为Module
任何类(即文件顶部没有package
定义)。 以下是Play 2.5.x的最新Activator模板的示例,我已经修改了该模板,用于演示在应用程序启动和关闭时运行的代码:
在services/Say.scala
,这将是一个简单的服务,说“你好!” 在启动和“再见!” 当应用程序关闭时:
package services
import javax.inject._
import play.api.inject.ApplicationLifecycle
import scala.concurrent.Future
trait Say {
def hello(): Unit
def goodbye(): Unit
}
@Singleton
class SayImpl @Inject() (appLifecycle: ApplicationLifecycle) extends Say {
override def hello(): Unit = println("Hello!")
override def goodbye(): Unit = println("Goodbye!")
// You can do this, or just explicitly call `hello()` at the end
def start(): Unit = hello()
// When the application starts, register a stop hook with the
// ApplicationLifecycle object. The code inside the stop hook will
// be run when the application stops.
appLifecycle.addStopHook { () =>
goodbye()
Future.successful(())
}
// Called when this singleton is constructed (could be replaced by `hello()`)
start()
}
在Module.scala中,
import com.google.inject.AbstractModule
import services._
/**
* This class is a Guice module that tells Guice how to bind several
* different types. This Guice module is created when the Play
* application starts.
* Play will automatically use any class called `Module` that is in
* the root package. You can create modules in other locations by
* adding `play.modules.enabled` settings to the `application.conf`
* configuration file.
*/
class Module extends AbstractModule {
override def configure() = {
// We bind the implementation to the interface (trait) as an eager singleton,
// which means it is bound immediately when the application starts.
bind(classOf[Say]).to(classOf[SayImpl]).asEagerSingleton()
}
}
您可能会发现一些有用的资源是Scala依赖注入(DI)文档和Guice文档 。 Guice是Play使用的默认DI框架。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.