前言
前陣子,有動態定時任務的需求,工期緊張且專案中未引入Quartz,
此時,似乎只剩下Spring Boot提供的定時任務可以考慮了,
調研
Spring Boot中定時任務,一般是使用@Scheduled注解進行標注,可以設定對應的cron運算式或者設定運行間隔周期,
樣例代碼如下所示:
@Scheduled(cron="0/5 * * * * ?")
void testPlaceholder1() {
System.out.println("Execute at " + System.currentTimeMillis());
}
不過使用注解標注定時任務,無法滿足定時任務周期定時更新的需求,
解救
查詢資料,發現可以使用繼承SchedulingConfigurer介面,實作動態定時任務,
@Slf4j
@Configuration
public class ImepStatusSchedulingConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(
()->{
// 業務邏輯
},
triggerContext -> {
// 此處,cron運算式從資料庫查詢得到
String cron = cronMapper.getCron();
// 根據cron運算式,構建CronTrigger,計算下一次的執行時間
CronTrigger trigger = new CronTrigger(cron);
return trigger.nextExecutionTime(triggerContext);
}
);
}
}
由代碼可知,每次運行定時任務時,均會動態計算下一次的運行時間點,
改動
Cron運算式比較復雜(專案由多人維護),而需求里只要求支持間隔固定秒數執行任務,
因此CronTrigger不再適合,因此需要進行相應改動,改動如下所示:
// 出于篇幅,此處省略無關代碼
triggerContext -> {
// 此處,duration可以從資料庫查詢得到
int duration = 1;
Date date = triggerContext.lastCompletionTime();
if (date != null) {
Date scheduled = triggerContext.lastScheduledExecutionTime();
if (scheduled != null && date.before(scheduled)) {
// Previous task apparently executed too early...
// Let's simply use the last calculated execution time then,
// in order to prevent accidental re-fires in the same second.
date = scheduled;
}
} else {
date = new Date();
}
date.setTime(date.getTime() + duration * 1000);
return date;
}
如此,就實作了動態設定間隔秒數的定時任務,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/349.html
標籤:Java
上一篇:2020年史詩級‘面試寶典’橫空而出,金九銀十就靠“它”漲薪了
下一篇:ProGuard使用檔案
