一、引言
1.1 简介
Quartz:Quartz Enterprise Job Scheduler
是一个定时任务调度框架。比如你遇到这样的问题:
想在30分钟后,查看订单是否支付,未支付则取消订单
想在每月29号,信用卡自动还款
...
想定时在某个时间,去做某件事(任务)。
Quartz是要做定时任务的调度,设置好触发时间规则,以及相应的任务(Job)即可。
二、Quartz使用
2.1 导入依赖
<dependencies><!--Quartz任务调度--><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.2</version></dependency></dependencies>
2.2 定义Job
/*** 工作类的具体实现,即需要定时执行的“某件事”* */public class MyJob implements Job {//执行public void execute(JobExecutionContext context) throws JobExecutionException {//创建工作详情JobDetail jobDetail=context.getJobDetail();//获取工作的名称String jobName = jobDetail.getKey().getName();//任务名String jobGroup = jobDetail.getKey().getGroup();//任务groupSystem.out.println("job执行,job:"+jobName+" group:"+jobGroup);System.out.println(new Date());}}
2.3 API测试
import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;import java.util.GregorianCalendar;public class TestQuartz {public static void main(String[] args) throws Exception{//创建scheduler,调度器Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();//定义一个Trigger,触发条件类Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1") //定义name/group.startNow()//设置开始时间,一旦加入scheduler,表示立即生效,即开始计时.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3) //每隔3秒执行一次//.repeatForever()) //一直执行,直到结束时间.withRepeatCount(3))//设置执行次数//设置结束时间(注:月份默认从0开始).endAt(new GregorianCalendar(,10,22,17,30,10).getTime()).build();//定义一个JobDetailJobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("job1","group1") //定义name/group.build();//调度器 中加入 任务和触发器scheduler.scheduleJob(job, trigger);//启动任务调度scheduler.start();}}
2.4 默认配置
# 名为:quartz.properties,放置在classpath下,如果没有此配置则按默认配置启动
# 指定调度器名称,非实现类
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
# 指定线程池实现类
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
# 线程池线程数量
org.quartz.threadPool.threadCount = 10
# 优先级,默认5
org.quartz.threadPool.threadPriority = 5
# 非持久化job
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
2.5 核心类说明
Scheduler:调度器。所有的调度都是由它控制,是Quartz的大脑,所有任务都是由它来管理
Job:任务,想定时执行的事情(定义业务逻辑)
JobDetail:基于Job,进一步包装。其中关联一个Job,并为Job指定更详细的属性,比如标识等
Trigger:触发器。可以指定给某个任务,指定任务的触发机制。
三、Trigger
3.1 SimpleTrigger
以一定的时间间隔(单位是毫秒)执行的任务。
指定起始和截止时间(时间段)
指定时间间隔、执行次数
示例:
SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1) //每秒执行一次.repeatForever())// 不限执行次数.endAt(new GregorianCalendar(, 11, 11, 2, 24, 0).getTime()).build();
SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMinutes(3) // 每3分钟执行一次.withRepeatCount(3)) // 执行次数不超过3次.endAt(new GregorianCalendar(, 11, 11, 2, 24, 0).getTime()) .build();
3.2 CronTrigger 【重点
】
适合于更复杂的任务,它支持类型于Linux Cron的语法(并且更强大)。
指定Cron表达式即可
示例:
//每两秒执行一次 涉及到cron表达式 TriggerBuilder<Trigger> triggerTriggerBuilder = TriggerBuilder.newTrigger();CronTrigger build1 = triggerTriggerBuilder.withIdentity("trigger", "triggerGroup").withSchedule(CronScheduleBuilder.cronSchedule("*/2 * * * * ?")).endAt(new GregorianCalendar(,9,22,14,31,30).getTime()).build();
3.2.1 Cron表达式组成
表达式组成:"秒 分 时 日 月 星期几 [年]" ,其中"年" 是可选的,一般不指定。
如:"10 20 18 3 5 ?"代表"5月3日18点20分10秒,星期几不确定 "
3.2.2 Cron表达式符号
表达式中可使用的特殊符号的含义如下
3.2.3 Cron表达式示例
演示实例
四、Spring整合Quartz 【重点
】
4.1 依赖
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.7</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.0.3.RELEASE</version></dependency><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.2</version></dependency></dependencies>
4.2 定义Job
定义一个Job类
public class MyJob implements Job {public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {System.err.println("job 执行"+new Date());}}
4.3 配置applicationContext.xml
调度器 SchedulerFactoryBean
触发器 CronTriggerFactoryBean
JobDetail JobDetailFactoryBean
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/schema/beans /schema/beans/spring-beans.xsd"><!--Spring整合Quartz进行配置遵循下面的步骤:1:定义工作任务的Job2:定义触发器Trigger,并将触发器与工作任务绑定3:定义调度器,并将Trigger注册到Scheduler--><!-- 1:定义任务的bean ,这里使用JobDetailFactoryBean,也可以使用MethodInvokingJobDetailFactoryBean ,配置类似--><bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"><!-- 设置name属性--><property name="name" value="myJob"></property><!-- 设置group属性--><property name="group" value="myJobGroup"></property><!-- 设置jobClass,找到实现job接口的类--><property name="jobClass" value=".MyJob"></property></bean><!-- 触发器--><bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"><!-- 设置触发器name--><property name="name" value="myTrigger"></property><!-- 设置触发器的分组--><property name="group" value="myTriggerGroup"></property><!-- 传入任务--><property name="jobDetail" ref="jobDetail"></property><!-- 设置cron表达式--><property name="cronExpression" value="* * * * * ?"></property></bean><!-- 调度器--><bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><!-- 传入触发器--><property name="triggers"><list><ref bean="cronTrigger"/></list></property><!-- 两种方式来传入quartz的配置文件--><!-- <property name="configLocation" value="classpath:quartz.properties"></property>--><property name="quartzProperties"><value># 指定调度器名称,实际类型为:QuartzSchedulerorg.quartz.scheduler.instanceName = MyScheduler# 指定连接池org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool# 连接池线程数量org.quartz.threadPool.threadCount = 11# 优先级org.quartz.threadPool.threadPriority = 5# 不持久化joborg.quartz.jobStore.class = org.quartz.simpl.RAMJobStore</value></property></bean></beans>
4.4 操作
4.4.1 启动任务
工厂启动,调度器启动,任务调度开始(这里注意最好放在主线程里面,并且不要使用junit测试来运行,否则有可能出不来结果,无法暂停任务)
public static void main(String[] args) throws InterruptedException, SchedulerException { // 工厂启动,任务启动,工厂关闭,任务停止ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");}
4.4.2 任务操作
4.4.2.1 删除任务
public static void main(String[] args) throws InterruptedException, SchedulerException { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");System.out.println("=============");StdScheduler scheduler = (StdScheduler) context.getBean("scheduler");System.out.println(scheduler.getClass());Thread.sleep(7000);// 删除Jobscheduler.deleteJob(JobKey.jobKey("myJob","myJobGroup"));}
4.4.2.2 暂停、恢复
public static void main(String[] args) throws InterruptedException, SchedulerException { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");System.out.println("=============");StdScheduler scheduler = (StdScheduler) context.getBean("scheduler");System.out.println(scheduler.getClass());Thread.sleep(7000);// 暂停,恢复工作scheduler.pauseJob(JobKey.jobKey("myJob","myJobGroup"));// 暂停工作Thread.sleep(3000);scheduler.resumeJob(JobKey.jobKey("myJob","myJobGroup"));// 恢复工作}
4.4.2.3 批量操作
public static void main(String[] args) throws InterruptedException, SchedulerException { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");System.out.println("=============");StdScheduler scheduler = (StdScheduler) context.getBean("scheduler");System.out.println(scheduler.getClass());Thread.sleep(7000);GroupMatcher<JobKey> group1 = GroupMatcher.groupEquals("myJobGroup");scheduler.pauseJobs(group1); // 暂停组中所有工作Thread.sleep(7000);scheduler.resumeJobs(group1); // 恢复组中所有工作 }