我正在尝试在Grails 2.2.4中采用Quartz插件(:quartz:1.0.1)并试图弄清楚如何允许开发和测试使用与 生产环境 中所需的不同的计划,而无需更改代码部署到每个 .
Here is my experience.
我正在使用JDBC JobStore和Quartz Monitor插件(:quartz-monitor:1.0) . 所以我的工作定义如下:
class TestJob {
static triggers = {
cron name: 'testTrigger', startDelay: 1000, cronExpression: '0 0/1 * * * ?'
}
...
}
当我运行Grails应用程序时,会为作业设置触发器,存储在数据库中,然后开始执行 . 如果我进入并通过Quartz Monitor对cron表达式进行有意更改,则会反映在数据库和执行计划中 .
如果我现在重新启动应用程序,则触发器将更改回作业中定义的内容 . 因此,使用这种方法,我几乎坚持使用触发器块中的任何内容 . 如果我完全从代码中删除触发器块,那么数据库定义将保持不变并控制计划,这似乎是一种改进 .
所以我认为在Job中没有定义任何触发器是有道理的,但是这让我试图弄清楚如何首先加载触发器并且不会覆盖有意的更改 . 似乎在配置中添加一个块(可能在外部配置文件中)来定义触发器是有意义的 . 据我所知,我需要写一些东西来解析它在启动时(在BootStrap?中)并通过Quartz API应用它 .
在我的所有文档阅读和谷歌搜索中都缺少这样的东西吗?或许我可能会以更为根本的方式做错事 .
Update with some implementation details
汉斯给了我一些关于什么应该适用于我的情况的想法 .
我最终关闭了JDBC作业存储,因为我认为配置应该是触发的权限 . 我将作业/触发器信息放入外观配置文件中,如下所示 .
quartzJobs: [
'TestJob': [
cronTriggers: [
cronExpression: '0 0 7 ? * 2-6'
]
]
]
然后我在BootStrap中调用了一些看起来像这样的代码 .
def jobs = grailsApplication.config.quartzJobs
if (jobs) {
jobs.each { job, details ->
List triggers = (details?.cronTriggers instanceof Map) ? [details.cronTriggers]: details.cronTriggers
if (triggers) {
def j = grailsApplication.mainContext.getBean(job)
triggers.each { trigger ->
String cronExpression = trigger.cronExpression ?: '1 1 1 1 1 ? 2099'
j.schedule(cronExpression)
}
}
}
}
3 回答
您可以将配置放在
Config.groovy
中,也可以放在从grails.config.locations
读取的属性文件中 .然后在你
BootStrap.groovy
你可以这样做:在此
cronExpression
是您在属性文件中选择的属性的名称 .有关可用的不同
Job.schedule()
方法,请参阅http://grails-plugins.github.io/grails-quartz/guide/triggers.html .您可以执行以下操作以根据当前环境更改触发器:
Update
汉斯解决方案可能更容易一些,但是如果它已经存在,那么另一个不会重新创建触发器 . :)
我重命名了
triggers
块,以便插件找不到任何触发器 .然后我重用
QuartzGrailsPlugin.groovy
中的代码从defaultTriggers
闭包创建触发器,并在它尚不存在时安排它 .通过查看
QuartzGrailsPlugin.groovy
中的doWithApplicationContext
,扩展代码以循环遍历所有作业应该不会太困难 .虽然有点吵 . 我认为最好将其隐藏在服务中并从
Bootstrap
调用它而不是内联 .BootStrap.groovy中
它可能不是你的方法.1327304_方法 . 此条件可用于基于当前Grails环境以及单独定义的cron表达式跳过执行 . 作为一个非常简单的例子: