小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
1. 两个Calendar类
Java.util包中有一个Calendar日历类,在使用Quartz框架时,使用日历类时却错误引用了Quertz框架中org.quartz包下的Calendar,导致发生了一些错误。
下面就来学习一下,Quertz框架中的Calendar是用来干什么的。
2. Quartz中的组织结构
Calendar作为一个顶层接口,其相关实现结构为:
结构图中虽然有很多的实现类,但是由于AnnualCalendar等类继承BaseCalendar类的同时还实现了Calendar接口,会在结构中重复显示,去除重复的结构可以表示为:
- Calender,接口
- BaseCalendar,类,实现Calender接口
- AnnualCalendar类,继承BaseCalendar、同时实现Calender
- MonthlyCalendar类,继承BaseCalendar、同时实现了Calender
- WeeklyCalendar类,继承BaseCalendar、同时实现了Calender
- DailyCalendar类,继承BaseCalendar
- HolidayCalendar类,继承BaseCalendar
- CronCalendar类,继承BaseCalendar
- BaseCalendar,类,实现Calender接口
3. 实现功能
了解Calender的结构信息后,便可以对实现类逐个击破,看一下实现的功能。
- AnnualCalendar:年度日历类,可以设置一年中的一组日期,生效后表示这些日期时间触发器都不会生效触发,粒度在日
//国庆节放假,不触发
AnnualCalendar annualCalendar = new AnnualCalendar();
Calendar calendar = new GregorianCalendar();
calendar.add(Calendar.MONTH,10);
calendar.add(Calendar.DATE,1);
annualCalendar.addExcludedDate(calendar)
- BaseCalendar:日历的基类,增加了一些额外的方法,如果需要可以实现该基类
- CronCalendar:使用cron表达式来设置触发器不触发的时间(段)
//cron表达式,如晚上22:00-23:00停止触发
CronCalendar calendar = new CronCalendar("* * 22-23 ? * *");
- DailyCalendar:日度日历类,设置一天中的某个时间段内触发器是否触发,setInvertTimeRange(false)表示不触发
//中午11:45-13:30午休,不触发
DailyCalendar dailyCalendar = new DailyCalendar("11:45:00", "13:30:00");
dailyCalendar.setInvertTimeRange(false);
- HolidayCalendar:节假日日历类,可以设置多年份的日期触发器失效,粒度在日
//设置1024程序员节日,触发器停止执行
HolidayCalendar holidayCalendar = new HolidayCalendar();
Calendar calendar = new GregorianCalendar(2021, 24, 10);
holidayCalendar.addExcludedDate(calendar);
- MonthlyCalendar:月度日历类,设置一个月中的哪些日期不触发触发器
//设置每月1号和15号不触发
MonthlyCalendar monthlyCalendar = new MonthlyCalendar();
monthlyCalendar.setDayExcluded(1, true);
monthlyCalendar.setDayExcluded(15, true)
- WeeklyCalendar:周日历类,设置一周中的周几不触发
//设置周六日双休
WeeklyCalendar weeklyCalendar = new WeeklyCalendar();
weeklyCalendar.setDayExcluded(Calendar.SATERDAY, true);
weeklyCalendar.setDayExcluded(Calendar.SUNDAY, true);
- 多个日历对象组合使用
//设置周五晚上20:00-21:00不触发
DailyCalendar dailyCalendar = new DailyCalendar("20:00:00", "21:00:00");
dailyCalendar.setInvertTimeRange(false);
WeeklyCalendar weeklyCalendar = new WeeklyCalendar(dailyCalendar);
weeklyCalendar.setDayExcluded(Calendar.FRIDAY, true);
4. 配置流程
- 选择创建日历对象
- 设置日历时间段策略
- 将日历对象配置到触发器中
- 将日历对象注册到调度器中
- 调度器执行触发器和任务
示例代码:
//①-②选择合适的日历对象创建,并设置不触发的策略
DailyCalendar dailyCalendar = new DailyCalendar("11:45:00", "13:30:00");
dailyCalendar.setInvertTimeRange(false);
//③将日历对象信息配置到触发器中,使用.modifiedByCalendar("dailyCalendar")
SimpleTrigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.startNow()
.withSchedule(simpleSchedule()
.withIntervalInSeconds(3)
.repeatForever())
.modifiedByCalendar("dailyCalendar")
.build();
//④-⑤将日历注册到调度器中,并执行调度器定时触发任务
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler scheduler = sf.getScheduler();
sched.addCalendar("dailyCalendar", dailyCalendar, false, false);
scheduler.scheduleJob(job, trigger);
5. 总结
以上就是Quartz框架中的Calendar的作用和使用方法,尽管Quartz为我们提供了一整套的定时策略,并可以根据节假日等排除日期时间,但实际使用时,大部分的时间策略都可以使用cron表达式来完成。在创建触发器时使用类型为CronTrigger的触发器对象可快速完成自定义时间的定时任务,更简单方便。