启动时依赖于 运行 应用程序的初始化服务 class 的问题 (play 2.4 / scala)
Issues with initializing service class that has dependency on running application on startup (play 2.4 / scala)
我目前正在研究在我们的 play 2.4 应用程序中使用 Quartz。
最初,我尝试通过 Global
对象初始化所有内容,并且一切正常。
现在,我试图摆脱 Global
利用模块基础设施。
这是我到目前为止所拥有的。
JobSchedulingService
@Singleton
class JobSchedulingService @Inject()(lifecycle: ApplicationLifecycle) extends ClassLogger{
lazy val schedulerFactory = current.injector.instanceOf[StdSchedulerFactory]
lazy val scheduler = schedulerFactory.getScheduler
/**
* Let's make sure that scheduler shuts down properly
*/
lifecycle.addStopHook{ () =>
Future.successful{
if (scheduler.isStarted) {
scheduler.shutdown(true)
}
}
}
protected def init() : Unit = {
logger.info("Initializing scheduler...")
scheduler.start()
}
init()
}
SchedulerModule - 这里用于初始化上面的服务。
class SchedulerModule extends AbstractModule{
override def configure(): Unit = {
bind(classOf[JobSchedulingService]).asEagerSingleton
}
}
并且在我的 application.conf
中添加了:
play.modules.enabled += "scheduling.modules.SchedulerModule"
它看起来很狭窄。但是,当应用程序启动时出现异常:
2016-03-23 00:07:42,173 INFO s.JobSchedulingService - Initializing
scheduler... 2016-03-23 00:07:42,213 ERROR application -
! @6pfp72mh6 - Internal server error, for (GET) [/] ->
play.api.UnexpectedException: Unexpected exception[CreationException:
Unable to create injector, see the following errors:
1) Error injecting constructor, java.lang.RuntimeException: There is
no started application at
scheduling.JobSchedulingService.(JobSchedulingService.scala:15)
at
scheduling.modules.SchedulerModule.configure(SchedulerModule.scala:11)
(via modules: com.google.inject.util.Modules$OverrideModule ->
scheduling.modules.SchedulerModule) while locating
scheduling.JobSchedulingService
...
问题是,在我们的应用程序中,调度程序基于关闭持久性作业存储,并且应该在应用程序重新启动时重新启动。同样,当我通过 Global
完成时,它工作得很好。
如何解决这个问题?在启动时初始化实例的正确方法是什么?
谢谢,
嗯...
我想我刚刚解决了它。
问题似乎不是 class 的实际初始化,而是这一行:
lazy val schedulerFactory = current.injector.instanceOf[StdSchedulerFactory]
一旦我将其更改为:
lazy val schedulerFactory = new StdSchedulerFactory
它开始工作了。
希望对某人有所帮助
您可能应该对所有内容都使用依赖注入。像这样注入调度程序..
class JobSchedulingService @Inject()(lifecycle: ApplicationLifecycle, schedulerFactory: StdSchedulerFactory) extends ClassLogger{
lazy val scheduler = schedulerFactory.getScheduler
我目前正在研究在我们的 play 2.4 应用程序中使用 Quartz。
最初,我尝试通过 Global
对象初始化所有内容,并且一切正常。
现在,我试图摆脱 Global
利用模块基础设施。
这是我到目前为止所拥有的。
JobSchedulingService
@Singleton
class JobSchedulingService @Inject()(lifecycle: ApplicationLifecycle) extends ClassLogger{
lazy val schedulerFactory = current.injector.instanceOf[StdSchedulerFactory]
lazy val scheduler = schedulerFactory.getScheduler
/**
* Let's make sure that scheduler shuts down properly
*/
lifecycle.addStopHook{ () =>
Future.successful{
if (scheduler.isStarted) {
scheduler.shutdown(true)
}
}
}
protected def init() : Unit = {
logger.info("Initializing scheduler...")
scheduler.start()
}
init()
}
SchedulerModule - 这里用于初始化上面的服务。
class SchedulerModule extends AbstractModule{
override def configure(): Unit = {
bind(classOf[JobSchedulingService]).asEagerSingleton
}
}
并且在我的 application.conf
中添加了:
play.modules.enabled += "scheduling.modules.SchedulerModule"
它看起来很狭窄。但是,当应用程序启动时出现异常:
2016-03-23 00:07:42,173 INFO s.JobSchedulingService - Initializing scheduler... 2016-03-23 00:07:42,213 ERROR application -
! @6pfp72mh6 - Internal server error, for (GET) [/] ->
play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:
1) Error injecting constructor, java.lang.RuntimeException: There is no started application at scheduling.JobSchedulingService.(JobSchedulingService.scala:15) at scheduling.modules.SchedulerModule.configure(SchedulerModule.scala:11) (via modules: com.google.inject.util.Modules$OverrideModule -> scheduling.modules.SchedulerModule) while locating scheduling.JobSchedulingService
...
问题是,在我们的应用程序中,调度程序基于关闭持久性作业存储,并且应该在应用程序重新启动时重新启动。同样,当我通过 Global
完成时,它工作得很好。
如何解决这个问题?在启动时初始化实例的正确方法是什么?
谢谢,
嗯... 我想我刚刚解决了它。
问题似乎不是 class 的实际初始化,而是这一行:
lazy val schedulerFactory = current.injector.instanceOf[StdSchedulerFactory]
一旦我将其更改为:
lazy val schedulerFactory = new StdSchedulerFactory
它开始工作了。
希望对某人有所帮助
您可能应该对所有内容都使用依赖注入。像这样注入调度程序..
class JobSchedulingService @Inject()(lifecycle: ApplicationLifecycle, schedulerFactory: StdSchedulerFactory) extends ClassLogger{
lazy val scheduler = schedulerFactory.getScheduler