# Quartz教程 - 6 调度器
# 6.1 Calendar例外
如果我们想在某些时候不执行任务,例如有一个任务,一年每天都会执行,但是想在节假日不执行,该如何做呢?
这个时候,就可以使用例外规则的调度器。在 Quartz 中可以使用 Calendar 来定义例外规则。
举个栗子:
org.quartz.Calendar
在Quartz 中是一个接口,它有很多的实现类,我们这里演示一下,在指定的日期不执行任务。
主要有三个步骤:
- 定义例外
// 1.定义例外
AnnualCalendar holidays = new AnnualCalendar();
// 2024年元旦不执行
Calendar newYear = new GregorianCalendar(2024, Calendar.JANUARY, 1);
holidays.setDayExcluded(newYear, true);
// 2024年中秋不执行
Calendar middleAutumn = new GregorianCalendar(2024, Calendar.SEPTEMBER, 17);
holidays.setDayExcluded(middleAutumn, true);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- 将例外添加到调度器中
// 2.将自定义的 Calendar 添加到 Scheduler 中
scheduler.addCalendar("holidays", holidays, false, false);
1
2
2
第三个参数表示已存在具有相同名称的 Calendar
,将其替换为新的 Calendar
。如果设置为 false
,如果已存在具有相同名称的 Calendar
,则不会进行替换,而是保留现有的 Calendar
。
第四个参数如果设置为 true
,则更新与 Calendar
相关联的触发器(如果有的话)。如果设置为 false
,则不会更新与 Calendar
相关联的任何触发器。
- 在触发器中指定时候使用的例外
CronTrigger cronTrigger = TriggerBuilder.newTrigger()
.withIdentity("cronTrigger1", "cGroup1")
.withSchedule(CronScheduleBuilder.cronSchedule("*/2 * * * * ?"))
// 3.与自定义的 Calendar 关联
.modifiedByCalendar("holidays")
.build();
1
2
3
4
5
6
2
3
4
5
6
完整代码:
package com.doubibiji;
import com.doubibiji.job.MyJob;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.calendar.AnnualCalendar;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.concurrent.TimeUnit;
public class TestClass {
public static void main(String[] args) {
// 1.定义例外
AnnualCalendar holidays = new AnnualCalendar();
// 2024年元旦不执行
Calendar newYear = new GregorianCalendar(2024, Calendar.JANUARY, 1);
holidays.setDayExcluded(newYear, true);
// 2024年中秋不执行
Calendar middleAutumn = new GregorianCalendar(2024, Calendar.SEPTEMBER, 17);
holidays.setDayExcluded(middleAutumn, true);
// 定义jobDetail
JobDetail job = JobBuilder.newJob(MyJob.class)
.withIdentity("job1", "jGroup1")
.build();
// 创建一个 Cron 触发器
CronTrigger cronTrigger = TriggerBuilder.newTrigger()
.withIdentity("cronTrigger1", "cGroup1")
.withSchedule(CronScheduleBuilder.cronSchedule("*/2 * * * * ?"))
// 3.与自定义的 Calendar 关联
.modifiedByCalendar("holidays")
.build();
try {
// 定义调度器
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 2.将自定义的 Calendar 添加到 Scheduler 中
scheduler.addCalendar("holidays", holidays, false, false);
// 设置任务和触发器,由触发器进行分派任务
scheduler.scheduleJob(job, cronTrigger);
scheduler.start();
// 让主线程延迟执行,scheduler如果shutdown,则所有的定时任务会取消。
TimeUnit.SECONDS.sleep(20);
scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
上面的 AnnualCalendar 是 org.quartz.Calendar 接口的一个实现,org.quartz.Calendar
接口定义了日历的抽象,而具体的日历实现则有多种方式,其中包括一些内置的和自定义的实现。
一些常见的 Quartz 内置日历实现包括:
- AnnualCalendar(年度日历): 允许你指定每年的特定日期,标记为不执行的日期,比如节假日等。
- CronCalendar(Cron日历): 根据 Cron 表达式指定一组不执行的日期。
- DailyCalendar(每日日历): 允许你指定每天的特定时间段,任务只能在该时间段内触发。
- HolidayCalendar(节假日日历): 类似 AnnualCalendar,允许你指定一年中不执行任务的特定日期。
- MonthlyCalendar(每月日历): 允许你指定每月的特定日期,标记为不执行的日期。
这些是 Quartz 中常见的内置日历实现,每种日历都有其特定的用途和功能。除了这些内置的日历实现外,你还可以实现自定义的 org.quartz.Calendar
接口,以满足你特定的业务需求。通过实现这个接口,你可以定义自己的日历逻辑,用于控制任务的执行时间。