Quartz
定时任务框架Quartz-(一)Quartz入门与Demo搭建
1.Quartz
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能:
- 持久性作业 - 就是保持调度定时的状态;
- 作业管理 - 对调度作业进行有效的管理;
Quartz的基本组成部分:
- 调度器:Scheduler
- 任务:JobDetail
- 触发器:Trigger,包括SimpleTrigger和CronTrigger
2.Quartz核心详解
Quartz框架中的几个重要参数:
- Job和JobDetail
- JobExecutionContext
- JobDataMap
- Trigger、SimpleTrigger、CronTrigger
2.1Job和JobDetail
Job是Quartz中的一个接口,接口下只有execute方法,在这个方法中编写业务逻辑。
接口中的源码:
package org.quartz;
public interface Job {
void execute(JobExecutionContext var1) throws JobExecutionException;
}
JobDetail用来绑定Job,为Job实例提供许多属性:
- name
- group
- jobClass
- jobDataMap
JobDetail绑定指定的Job,每次Scheduler调度执行一个Job的时候,首先会拿到对应的Job,然后创建该Job实例,再去执行Job中的execute()的内容,任务执行结束后,关联的Job对象实例会被释放,且会被JVM GC清除。
为什么设计成JobDetail + Job,不直接使用Job
JobDetail定义的是任务数据,而真正的执行逻辑是在Job中。
这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。而JobDetail & Job 方式,Sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访问的问题。
2.2JobExecutionContext
JobExecutionContext中包含了Quartz运行时的环境以及Job本身的详细数据信息。
当Schedule调度执行一个Job的时候,就会将JobExecutionContext传递给该Job的execute()中,Job就可以通过JobExecutionContext对象获取信息。
主要信息有:
2.3JobExecutionContext
JobDataMap实现了JDK的Map接口,可以以Key-Value的形式存储数据。
JobDetail、Trigger都可以使用JobDataMap来设置一些参数或信息,
Job执行execute()方法的时候,JobExecutionContext可以获取到JobExecutionContext中的信息:
如:
JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class) .usingJobData("jobDetail1", "这个Job用来测试的")
.withIdentity("job1", "group1").build();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")
.usingJobData("trigger1", "这是jobDetail1的trigger")
.startNow()//立即生效
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(1)//每隔1s执行一次
.repeatForever()).build();//一直执行
Job执行的时候,可以获取到这些参数信息:
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println(jobExecutionContext.getJobDetail().getJobDataMap().get("jobDetail1"));
System.out.println(jobExecutionContext.getTrigger().getJobDataMap().get("trigger1"));
String printTime = new SimpleDateFormat("yy-MM-dd HH-mm-ss").format(new Date());
System.out.println("PrintWordsJob start at:" + printTime + ", prints: Hello Job-" + new Random().nextInt(100));
}
2.4Trigger、SimpleTrigger、CronTrigger
2.4.1Trigger
Trigger是Quartz的触发器,会去通知Scheduler何时去执行对应Job。
new Trigger().startAt():表示触发器首次被触发的时间;
new Trigger().endAt():表示触发器结束触发的时间;
2.4.2SimpleTrigger
SimpleTrigger可以实现在一个指定时间段内执行一次作业任务或一个时间段内多次执行作业任务。
下面的程序就实现了程序运行5s后开始执行Job,执行Job 5s后结束执行:
Date startDate = new Date();
startDate.setTime(startDate.getTime() + 5000);
Date endDate = new Date();
endDate.setTime(startDate.getTime() + 5000);
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")
.usingJobData("trigger1", "这是jobDetail1的trigger")
.startNow()//立即生效
.startAt(startDate)
.endAt(endDate)
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(1)//每隔1s执行一次
.repeatForever()).build();//一直执行
2.4.3CronTrigger
CronTrigger功能非常强大,是基于日历的作业调度,而SimpleTrigger是精准指定间隔,所以相比SimpleTrigger,CroTrigger更加常用。CroTrigger是基于Cron表达式的,先了解下Cron表达式:
由7个子表达式组成字符串的,格式如下:
[秒] [分] [小时] [日] [月] [周] [年]