Spring+Quartz实现周末、节假日排除的定时任务

来源:互联网 发布:网络作者介绍 编辑:程序博客网 时间:2024/06/01 09:24

废话不多说,直接入主题。


需求:

         定时发送报表数据到企业号关注用户上,但是这些数据周末和节假日。


问题:

       直接上图:

 

很明显quartz的trigger,有如上框出来的几个:CalendaerIntervalTriggerImpl、CronTriggerImpl、DailyTimeIntervalTriggerImpl、SimpleTriggerImpl

项目里面用的比较多的是SimpleTriggerImpl和CronTriggerImpl


SimpleTriggerImpl的构造函数中有几个很重要的参数:startTime(开始时间)、endTime(结束时间)、repeatCount(重复数次)、repeatInterval(重复执行间隔),很明显,SimpleTriggerImpl就是为了在某个时间段内实现定时任务的重复执行的,还支持重复执行加间隔时间。


CronTriggerImpl的构造函数中有这几个重要参数:startTime(开始时间)、endTime(结束时间)、cronExpression(定时表达式)、timeZone(时区),这个trigger是最常用的,cronExpression很强大,可以配置某年某月某日某时某分某秒定时执行任务,也支持时间间隔,8号到12号等,cronExpression用法此文就不赘述,详情可以去看官方文档。大家需要注意的是有个timeZone参数,它有个默认值,一般默认获取jvm所在时区,一定要注意,是jvm的当前时区。设置当前时区的代码如下:



就是因为如此,我们有时候会发现配置的定时任务并没有执行。这个时候需要考虑的是是不是jvm的当前时区与服务器端所在的时区是否一致。


CalendaerIntervalTriggerImpl与DailyTimeIntervalTriggerImpl也是间断重复执行实现类,所以问题来了,排除周末很容易,用cronExpression即可,但是怎么去排除节假日?

显然在Trigger上面做文章是不行的。


凡是有可能产生变化的地方,一个都不要放过!

spring里面有个SchedulerFactoryBean,它是用来管理quart任务的,调用什么trigger去执行哪个bean的业务方法。下图是这个类可以注入的属性:


显然没有能满足需求的配置属性。再看看它实现了什么接口,继承了什么类:






眼前一亮,看见calendars,感觉应该是有用的,于是追代码看看怎么使用calendars这个属性的:

此处省略一万字,我在写这边文章的时候没有找到,大家可以顺着这样的思路去找,找到的话请赐教,哈哈。


接下来看配置:



下面是HCalendar的源码,扩展了quartz的代码:



其中HolidayCalendar就是quartz自带的,但HolidayCalendar只支持单个日期的排除,不支持多个日期,因此做了这样的扩展。





0 0