Quartz基础概念
任务Job
Job就是我们要实现的任务类,每一个Job必须实现org.quartz.job接口,并实现接口定义的execte()方法。
触发器Trigger
Trigger为你执行任务的触发器,如每天下午3点定时发送一个邮件,Trigger将会设置3点进行执行该任务。 Trigger主要包含两种:SimpleTrigger和CronTrigger。
调度器Scheduler
Scheduler为任务的调度器,他会将Job和Trigger整合起来,负责基于Trigger设定的时间来执行Job。
Quartz的体系结构
代码示例
每10秒执行1次任务
/**
* 定时任务类
* @author HigginCui
* @date 2023/1/30 上午12:08
*/
public class QuartzTestJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(time+"----当前Quartz任务开始执行");
}
}
/**
* 任务调度器
* @author HigginCui
* @date 2023/1/30 上午12:09
*/
public class QuartzTestScheduler {
public static void main(String[] args) throws Exception{
//获取任务调度的实例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//定义任务调度实例,并与TestJob绑定,("testJob":任务的名称,需要唯一)
JobDetail jobDetail = JobBuilder
.newJob(QuartzTestJob.class)
.withIdentity("testJob","testJobGroup")
.build();
//定义触发器,马上执行一次,后面每10S执行一次
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("testTrigger","testTriggerGroup")
.startNow()
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(10))
.build();
//使用触发器来调度任务的执行
scheduler.scheduleJob(jobDetail,trigger);
//开始任务
scheduler.start();
}
}
关键参数概念解释
Job和JobDetail
- Job:工作任务调度的接口,任务类需要实现该接口,接口中定义了execute()方法(类似JDK提供的TimeTask的run()方法),在里面编写任务执行的业务逻辑。
- Job实例在Quartz中的生命周期:在调用execute方法前会创建一个新的job实例,当调用完成后,关联的Job对象实例会被释放,释放的实例会被垃圾回收。
- JobDetail:为Job实例提供设置属性,以及JobDetailMap成员变量属性,用来存储特定Job实例的状态信息,调度器需要借助JobDetail对象来添加Job实例。
JobDetail重要属性:name,group,jobClass,jobDataMap
name(任务名称)------jobDetail.getKey().getName();
group(组名称)------jobDetail.getKey().getGroup()
jobClass(任务类)------jobDetail.getJobClass().getName()
jobDataMap------jobDetail.getJobDataMap()
- Job和JobDetail的关系
JobExecutionContext
当Scheduler调用一个Job,就会将JobExecutionContext传递给Job的execute()方法,Job能通过JobExecutionContext来获取Job明细数据和Quartz运行环境信息。
JobDataMap
1.使用Map获取
- 在进行任务调度时,JobDataMap存储在Job ExecutionContext中。
- JobDataMap可以用来装载任何可序列化的数据对象,当job实例对象被执行时这些参数会传递给他。
- JobDataMap实现了JDK的Map接口,并且添加了非常方便的方法来存取基本数据类型。
【任务调度类】
public static void main(String[] args) throws Exception{
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
JobDetail jobDetail = JobBuilder
.newJob(QuartzTestJob.class)
.withIdentity("testJob","testJobGroup")
//这里传递一个上下文信息到jobDetail中
.usingJobData("externalInfo","jobDetail扩展信息")
.build();
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("testTrigger","testTriggerGroup")
.startNow()
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(10))
//这里传递一个上下文信息到trigger中
.usingJobData("externalInfo","trigger扩展信息")
.build();
//使用触发器来调度任务的执行
scheduler.scheduleJob(jobDetail,trigger);
//开始任务
scheduler.start();
}
【任务类】
public class QuartzTestJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(time+"----当前Quartz任务开始执行");
System.out.println("jobExecutionContext.getJobDetail().getJobDataMap().get("externalInfo")======="+jobExecutionContext.getJobDetail().getJobDataMap().get("externalInfo"));
System.out.println("jobExecutionContext.getTrigger().getJobDataMap().get("externalInfo")======="+jobExecutionContext.getTrigger().getJobDataMap().get("externalInfo"));
}
}
执行结果:
有状态的Job和无状态的Job
有状态的Job可以理解为多次Job调用期间可以持有一些状态信息,会存储在JobDataMap中,而默认的无状态的Job每次调用都会创建换一个新的DataJobMap。
新增一个注解 @PersistJobDataAfterExecution,就会变成有状态的Job,这样多次调用时,使用的是一个Job实例,即单例的Job。
Trigger
Quartz有不同类型的触发器,用的最多的是SimpleTrigger和CronTrigger。
Simple触发器
最为简单的一种触发器,使用在特定日期/时间启动,并且可以间隔重复执行n次的Job所设计的。 Simple触发器设置的关键参数:开始时间、结束时间、重复次数、时间间隔。
【代码示例】
//定义触发器,指定时间开始执行,后面每10S执行一次,执行3次
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("testTrigger","testTriggerGroup")
//什么时候开始执行
.startAt(new Date())
//每10s执行一次,执行3次(注:这里从0开始计数)
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(10).withRepeatCount(2))
.build();
Cron触发器
基于Cron表达式的调度,更为灵活。