转自原博客地址:http://blog.csdn.net/wangyongwyk/article/details/5534966
Quartz插件可以使Grails应用程序按照指定的时间间隔或cron表达式来执行调度任务。Grails系统通过spring配置使用Quartz Enterprise Job Scheduler 实现,但是编码时按照规约可以很容易的实现。
Grails-Quartz 0.4.1是当前稳定版本。Grails-Quartz 0.4.2是最新正在开发的版本。(已经发布了)
1 插件安装
在应用文件夹路径下键入以下命令
grails install-plugin quartz
如果以上命令由于某种原因不行,试一下下面这个
grails install-plugin http://cloud.github.com/downloads/nebolsin/grails-quartz/grails-quartz-0.4.1.zip
2 用法
调度任务(Scheduling Jobs)
在命令行键入“grails create-job”命令并输入任务名称,Grails会创建一个新的任务,并把它放到"grails-app/jobs"路径下。
class MyJob {
static triggers = {
simple name: 'mySimpleTrigger', startDelay: 60000, repeatInterval: 1000
}
def group = "MyGroup"
def execute(){
print "Job run!"
}
}
上述例子会等待1分钟后每秒调用execute方法一次。'repeatInterval' 和'startDelay'属性的单位是毫秒,值必须是int或long。如果这两个属性不指定,则使用默认值(repeatInterval为1分钟,startDelay为30秒)
jobs默认情况下在test环境不运行。
调度Cron任务(Scheduling a Cron Job)
可以使用cron表达式调度任务。
class MyJob {
static triggers = {
cron name: 'myTrigger', cronExpression: "0 0 6 * * ?"
}
def group = "MyGroup"
def execute(){ print "Job run!" }
}
组合触发器任务
可以使用组合触发器调度任务。
class MyJob {
static
triggers = {
simple name:'simpleTrigger', startDelay:10000, repeatInterval: 30000, repeatCount: 10
cron name:'cronTrigger', startDelay:10000, cronExpression: '0/6 * 15 * * ?'
custom name:'customTrigger', triggerClass:MyTriggerClass, myParam:myValue, myAnotherParam:myAnotherValue
}def execute() {
println "Job run!"
}
}
上面这个例子中,scheduler(调度器)启动10秒后,job会每隔30秒执行一次,一共执行11次(simpleTrigger);在15点时每6秒执行一次(15:00:00, 15:00:06, 15:00:12, … — 这个由'cronTrigger'配置的),自定义的触发器触发时执行。
三种触发器可以支持的参数如下
-
simple
:-
name
— 触发器的名称标识 -
startDelay
— 调度器启动与第一次执行任务之间的间隔 (单位:毫秒) -
repeatInterval
— 连续两次执行任务之间的时间间隔(单位:毫秒) -
repeatCount
— 任务执行(1 + repeatCount)
次之后停止 (=0
执行一次 或=-1
执行无限次)
-
-
cron
:-
name
— 触发器的名称标识 -
startDelay
— 调度器启动与第一次执行任务之间的间隔 (单位:毫秒) -
cronExpression
— cron表达式
-
-
custom
:-
triggerClass
— 自定义的实现了Trigger接口的类 - 自定义触发器的需要的其他参数
-
动态任务调度(Dynamic Jobs Scheduling)
从0.4.1版本开始,可以使用动态调度任务。
可以使用以下方法:
-
MyJob.schedule(String cronExpression, Map params?)
— 创建cron触发器; -
MyJob.schedule(Long repeatInterval, Integer repeatCount?, Map params?)
— 创建simple触发器: 间隔repeatInterval毫秒重复job repeatCount+1次; -
MyJob.schedule(Date scheduleDate, Map params?)
— 在指定日期调度执行一个任务; -
MyJob.schedule(Trigger trigger)
— 使用自定义触发器调度任务执行; -
MyJob.triggerNow(Map params?)
— 强制任务立刻执行.
每个方法都带有一个可选的‘params’参数。可以用它传递数据。
class MyJob {
…
def execute(context) {
println context.mergedJobDataMap.get('foo')
}
…
}// 在controller (或 service, 或其他地方):
MyJob.triggerNow([foo:"It Works!"
])
依赖注入和jobs(Dependency Injection and Jobs)
Jobs被配置为按名称自动绑定(auto-wiring by name),属性可以注入到jobs里。为获取data source可以声明def dataSource
或者一个Service类
def myService
Grails application context 配置为使用规约,因此大部分类型可以使用属性名称很简单地注入(即大多数情况下首字母小写)。
使用JobExecutionContext(Using JobExecutionContext)从0.3.2开始,你可以定义在job中这样定义execute方法def execute(context){},这由Quartz's JobExecutionContext提供。
如通过
context.getMergedJobDataMap()
提供一些参数给job一样,你可以从context中获取某些信息(触发器名称,上次执行时间,下次执行时间等)。如果你的job是有状态的(看下面的并发一节),JobExecutionContext中的job数据在每次执行job时也会持久化。
配置插件(Configuring the plugin)
从0.3版本开始,插件支持配置文件,配置内容保存在grails-app/conf/QuartzConfig.groovy文件中。语法与默认的Grails配置文件
Config.groovy
相同
。
在命令行键入'grails install-quartz-config',可以获得一个初始的
Quartz配置文件。文件内容大致如下:
quartz {
autoStartup = true
jdbcStore = false
}
environments {
test {
quartz {
autoStartup = false
}
}
}
目前支持的选项:
-
autoStartup
— 应用启动时,自动启动Quartz调度器 (默认值:true
) -
jdbcStore
— 如果需要Quartz持久化 jobs到DB时设置为true(默认值:false
),还需要提供quartz.properties
文件,确信所需的数据表在db中存在 (see Clustering section below for the sample config and automatic tables creation using Hibernate)
还可以创建
grails-app/conf/quartz.properties文件来为
Quartz调度器提供不同的选项
(参考 Quartz configuration reference ).
日志(Logging)
log被自动注入到你的job类里,但没有激活它。在 grails-app/conf/Config.groovy中配置如下语句即可设置log级别。debug 'grails.app.task'
hibernate会话和任务(Hibernate Sessions and Jobs)
默认配置每次job执行时绑定一个Hibernate会话。当你要open session或者domain类持久化操作时这是必须的。
如果你不使用,可以使用 'sessionRequired' 属性重载这个行为。
def sessionRequired = false
配置并发执行(Configuring concurrent execution)
默认Jobs可以并发执行,因此即使前一个同样的任务正在执行,一个新的任务也可以创建并执行。如果想重载这种行为,可以使用'concurrent' 属性
def concurrent = false