springboot配置动态定时任务 及 重复执行解决
背景:页面会有一个设置时间频率的输入框,这个频率也是定时任务的执行时间间隔,单位是分钟;
思路:按springboot的@Scheduled方式配置定时任务,其中有cron规则,和fixedRate、fixedDelay配置,配置规则是这样的,如,每5秒执行一次
@Scheduled(cron = "0/5 * * * * *") 这个配置可以在配置文件添加后@Value获取
@Scheduled(fixedRate = 5000) 这个是每5秒执行一次
@Scheduled(fixedDelay = 5000) 这个是每次任务结束后5秒执行
可以参考:http://www.wanqhblog.top/2018/02/01/SpringBootTaskSchedule/
如上配置,cron规则有些不太适用,因为单位是分钟;试试看用下面的俩种能不能实现
先试试写死执行时间
1.启动类加入注解@EnableScheduling
//这里开启定时任务 @EnableScheduling public class Application extends SpringBootServletInitializer {
public static void main(String[] args) { SpringApplication.run(Application.class, args); } } |
2.定时方法上加入@Scheduled
@Component public class AlarmTimeSchedule { /** * 固定cron配置定时任务 */ @Scheduled(fixedRate = 5000) public void doTask(){ System.out.println("执行了定时任务,时间为:"+new Date(System.currentTimeMillis())); }
} |
启动可以看到执行了
到这里,简单的定时完成了,现在触发是自带的,满足不了我们的需求,需要修改触发规则
1.先实现Spring提供的SchedulingConfigurer接口,可以看到重写了一个configureTasks方法
添加触发器属性:Trigger,里面有俩个参数:第一个是业务规则,第二个是触发器
这里的新的时间本来想简单的用 SimpleTrigger 触发实现,可是导入不了包,所以还是使用CronTrigger 触发器实现了,二者的区别可参考:https://blog.****.net/zixiao217/article/details/53075009
接着上面写: 执行逻辑
private Runnable doTask(){ return new Runnable(){ @Override public void run() { System.out.println("执行了定时任务,时间为:"+new Date(System.currentTimeMillis())); //测试是否执行 FailCount(newCron); //调用逻辑 } }; } |
这里的Runnable注意new出来,不然不执行 下面是新的触发规则
private Trigger getTrigger(){ return new Trigger(){ @Override public Date nextExecutionTime(TriggerContext triggerContext) { // 触发器 CronTrigger trigger = new CronTrigger(getCron()); return trigger.nextExecutionTime(triggerContext); } }; } public String getCron() { String newCron = alarmFailCountService.findtimes(); //这里的时间规则来源按自己需求获取 //String newCron = "0/20 * * * * ?"; //测试 if ("".equals(newCron)&&newCron==null) { throw new CacheException("The config cron expression is empty"); } if (!newCron.equals(cron)) { System.out.println((new StringBuffer("Cron has been changed to:'").append(newCron).append("'. Old cron was:'").append(cron).append("'").toString())); doTask(); cron = newCron; } return cron; } |
ok了,定时执行完成!
发现的问题:
定时任务跑了,但是触发却是一秒一次,一共会执行60次。
这个是因为定时设置问题,将*改成0就可以了。
我也看底层了,没找到文章里说的next,但是确实有lastTime的if判断,没看懂。
参考:https://blog.****.net/has330338724/article/details/80812438