客户的需求是,工作日是8-18点每20分钟执行一次,节假日是8-18点每2小时执行一次。
自己从网上查了一下,没有具体设置cron表达式为节假日和工作日的方法,所以只能自己动手了。
经过自己多次测试,我总结一下自己的想法:实现SchedulingConfigurer
实现SchedulingConfigurer类,在项目启动的时候把这些个定时任务扫描到定时任务里即可!
1、提前写一个定时任务,在每天凌晨2点,根据当前日期判断是节假日还是工作日,更新数据库储存的cron表达式。
@Component
@Slf4j
public class updateCronTask {
@Value("${ahhb.scheduled.cron.job}")
private String jobCron;
@Value("${ahhb.scheduled.cron.holiday}")
private String holidayCron;
@Autowired
private CheckHBMapper checkHBMapper;
@Scheduled(cron = "${ahhb.scheduled.cron.custInfo}")
public void updateCron() {
// 获取当天的是否为工作日
String dateCode = checkHBMapper.queryDateCode(new Date());
if (dateCode.equals("0")) { //工作日
log.info("日期"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"时为工作日,修改cron为:"+jobCron);
// 修改数据库,cron为工作日检测时间
checkHBMapper.updateCron(jobCron);
} else { //节假日
log.info("日期"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"时为节假日,修改cron为:"+holidayCron);
// 修改数据库,cron为节假日检测时间
checkHBMapper.updateCron(holidayCron);
}
}
}
2、直接实现SchedulingConfigurer类,重写configureTasks方法,结合上边每天定时储存的cron表达式,动态定时执行
@Component
@Slf4j
public class SendMsgTask implements SchedulingConfigurer {
@Autowired
private CheckHBMapper checkHBMapper;
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(
//1.添加任务内容(Runnable)
() -> {
log.info("执行动态定时任务: " + new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date()));
//这里是你业务要实现的方法
method();
},
//2.设置执行周期(Trigger)
triggerContext -> {
//2.1 从数据库获取执行周期
String cron = checkHBMapper.queryCron().getCronCode();
//2.2 返回执行周期(Date)
return new CronTrigger(cron).nextExecutionTime(triggerContext);
}
);
}
}
重点
重要的就是在triggerContext 的lombda表达式里,你的cron从数据库动态获取,因为提前咱们写了每天定时更新cron表达式根据不同需求,此时就可以判断是否为节假日或工作日去执行对应的cron表达式。