由于业务需求,需要提供一个能够让用户动态配置定时任务的入口,定时去同步数据
1、简单的业务处理,直接使用@Scheduled注解就能开启定时任务,例如在方法上@Scheduled(cron = “0 0/1 * * * ?”),书写cron表达式就能配置定时任务。
@Scheduled(cron = "0 0/1 * * * ?") public void execEveryDay() { checkPlan(); }
|
2、但是随着业务复杂化,使用注解目前是满足不了动态配置定时任务的,以下代码能够实现cron表达式的动态配置。
第一步,在启动类新增注解@EnableScheduling
@SpringBootApplication @EnableScheduling public class testApplication { public static void main(String[] args) { SpringApplication.run(testApplication .class, args); }
}
|
第二步,编写定时任务类
@Lazy(false) @Component @EnableScheduling @Slf4j public class OutPutTask implements SchedulingConfigurer { private String cron = "0 55 23 ? * *";
@Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.addTriggerTask(() -> { try { Boolean lockStatus = redisTemplate.opsForValue().setIfAbsent(RedisKeyPrefix.RECORD_OUT_PUT, new Date(), 1, TimeUnit.MINUTES); if (lockStatus == null || !lockStatus) { return; } log.info("产能计算定时任务{}", new Date()); recordOutput(); } finally { redisTemplate.delete(RedisKeyPrefix.RECORD_OUT_PUT); } }, triggerContext -> { cron = this.getCronString(); CronTrigger trigger; try { trigger = new CronTrigger(cron); return trigger.nextExecutionTime(triggerContext); } catch (Exception e) { trigger = new CronTrigger("0 55 23 ? * *"); return trigger.nextExecutionTime(triggerContext); } }); }
private String getCronString() { Date beginDate = dictService.getDayOutputBeginTime(new Date()); String hour = beginDate.toString().substring(11, 13); String min = beginDate.toString().substring(14, 16); String cron = "0 min hour ? * *"; return cron.replaceAll("min", min).replaceAll("hour", hour); }
|
然后我们只需要在页面上提供一个能够让用户配置定时任务的入口或者在数据库里配置cron表达式,就能实现动态配置。
如果面向的用户懂得cron表达式,也可以直接让用户配置cron表达式也是可以的,省的程序员进行额外的数据处理,只要配置正确,任何处理方式都行,例如:
点击确定后,会更新数据库,当定时任务时间到了,就会触发定时任务机制,重新设置定时任务。