Play框架Global Settings方法替代及Scala 2.5→2.6迁移时区设置咨询
迁移Joda DateTimeZone默认值设置的具体实现
你提到的DateTimeZone.setDefault(DateTimeZone.forID("Europe/London"))这种全局初始化操作,完全可以用Play的DI机制来实现——其实DI不只是用来获取实例,它还能精准控制代码的执行时机,刚好适配这种启动时的全局配置需求。这里有两种常用且靠谱的实现方式:
方式一:通过ApplicationLifecycle钩子执行
创建一个自定义Guice模块,绑定应用生命周期监听器,在应用启动时执行时区设置:
import com.google.inject.AbstractModule import play.api.inject.ApplicationLifecycle import org.joda.time.DateTimeZone import scala.concurrent.Future class DateTimeZoneModule extends AbstractModule { override def configure(): Unit = { bindListener(classOf[ApplicationLifecycle], (lifecycle: ApplicationLifecycle) => { // 应用启动时立即设置默认时区 DateTimeZone.setDefault(DateTimeZone.forID("Europe/London")) // 如果需要在应用关闭时执行清理逻辑,可在这里添加 lifecycle.addStopHook { () => Future.successful(()) } }) } }
然后在conf/application.conf里注册这个模块,让Play加载它:
play.modules.enabled += "com.yourpackage.DateTimeZoneModule"
方式二:用饿汉单例触发初始化
创建一个初始化类,在构造函数里执行时区设置,然后通过Guice绑定为EagerSingleton——这种单例会在应用启动时被立即实例化,构造函数里的代码也就自动执行了:
import org.joda.time.DateTimeZone class DateTimeZoneInitializer { // 构造函数执行时区设置 DateTimeZone.setDefault(DateTimeZone.forID("Europe/London")) }
接着在自定义模块里绑定它为饿汉单例:
import com.google.inject.AbstractModule class AppModule extends AbstractModule { override def configure(): Unit = { bind(classOf[DateTimeZoneInitializer]).asEagerSingleton() } }
同样要在application.conf里注册这个模块。
为什么这种方式可行?
Play 2.6+的DI体系(默认用Guice)会在应用启动阶段完成所有必要的实例绑定和初始化。不管是ApplicationLifecycle钩子还是饿汉单例,都能保证你的时区设置代码在应用处理请求之前执行,效果和原来Global里的初始化完全一致,而且更符合模块化设计,后续测试或扩展也更方便。
内容的提问来源于stack exchange,提问作者Pete Leaman
相关产品推荐
相关产品推荐

