Spring動態(tài)添加定時任務(wù)的實現(xiàn)思路
一、背景
在工作中,有些時候我們有些定時任務(wù)的執(zhí)行可能是需要動態(tài)修改的,比如: 生成報表,有些項目配置每天的8點生成,有些項目配置每天的10點生成,像這種動態(tài)的任務(wù)執(zhí)行時間,在不考慮分布式執(zhí)行的情況下,我們可以
使用 Spring Task來簡單的實現(xiàn)。
二、需求和實現(xiàn)思路
1、能夠動態(tài)的添加一個定時任務(wù)。
在Spring中存在一個類ThreadPoolTaskScheduler,它可以實現(xiàn)根據(jù)一個cron表達式來調(diào)度一個任務(wù),并返回一個ScheduledFuture對象。

2、能夠取消定時任務(wù)的執(zhí)行。
通過調(diào)用上一步的ScheduledFuture的cancel方法,就可以將這個任務(wù)取消。
3、動態(tài)的修改任務(wù)執(zhí)行的時間。
先取消任務(wù)。然后在重新注冊一個任務(wù)。
4、獲取定時任務(wù)執(zhí)行的異常
ThreadPoolTaskScheduler類中有一個設(shè)置ErrorHandler的方法,給自己實現(xiàn)的ErrorHandler即可。

提示:
- 在
Spring中我們通過@Scheduled注解來實現(xiàn)的定時任務(wù),底層也是通過ThreadPoolTaskScheduler來實現(xiàn)的。可以通過ScheduledAnnotationBeanPostProcessor類來查看。 ThreadPoolTaskScheduler的默認線程數(shù)是1,這個需要根據(jù)實際的情況進行修改。
三、代碼實現(xiàn)
此處只給出動態(tài)注冊定時任務(wù)和取消的定時任務(wù)的代碼。
package com.huan.study.task.jobs.tasks;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronExpression;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
* @author huan.fu 2021/7/8 - 下午2:46
*/
@Component
@Slf4j
public class DynamicCronTask implements InitializingBean {
@Autowired
private ThreadPoolTaskScheduler taskScheduler;
private ScheduledFuture<?> scheduledFuture;
@Override
public void afterPropertiesSet() throws Exception {
// 動態(tài)啟動一個定時任務(wù)
log.info("注冊一個定時任務(wù):每隔1秒執(zhí)行一次");
scheduledFuture = register("* * * * * ?");
// 取消一個調(diào)度
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(5);
log.info("取消調(diào)度");
scheduledFuture.cancel(false);
log.info("取消結(jié)果:" + scheduledFuture.isCancelled());
log.info("重新注冊一個定時任務(wù):每隔2秒執(zhí)行一次");
register("*/2 * * * * ?");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
private ScheduledFuture<?> register(String cron) {
// 高版本使用 CronExpression,低版本使用 CronSequenceGenerator
boolean validExpression = CronExpression.isValidExpression(cron);
log.info("cron:[{}]是合法的嗎:[{}]", cron, validExpression);
CronExpression expression = CronExpression.parse(cron);
LocalDateTime nextExecTime = expression.next(LocalDateTime.now());
if (null != nextExecTime) {
log.info("定時任務(wù)下次執(zhí)行的時間為:[{}]", nextExecTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}
return taskScheduler.schedule(new Runnable() {
@Override
public void run() {
log.info("我執(zhí)行了");
}
}, new CronTrigger(cron));
}
}
四、執(zhí)行結(jié)果

五、完整代碼
https://gitee.com/huan1993/spring-cloud-parent/tree/master/springboot/springboot-task
到此這篇關(guān)于Spring動態(tài)添加定時任務(wù)的實現(xiàn)思路的文章就介紹到這了,更多相關(guān)Spring定時任務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺析Java中Map與HashMap,Hashtable,HashSet的區(qū)別
HashMap和Hashtable兩個類都實現(xiàn)了Map接口,二者保存K-V對(key-value對);HashSet則實現(xiàn)了Set接口,性質(zhì)類似于集合2013-09-09
MyBatisPlus查詢報錯Unknow?column?‘id‘?in?‘field?list‘解決分析
這篇文章主要為大家介紹了MyBatisPlus查詢報錯Unknow?column?‘id‘?in?‘field?list‘解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09
java編程實現(xiàn)屏幕截圖(截屏)代碼總結(jié)
這篇文章主要介紹了java編程實現(xiàn)屏幕截圖(截屏)代碼,結(jié)合3個實例總結(jié)分析了Java截屏?xí)r頁面抓取及圖片保存的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11
mybatisPlus實現(xiàn)邏輯刪除,自動生成創(chuàng)建時間和更新時間方式
MyBatisPlus框架中,通過@TableField(fill=FieldFill.INSERT)和@TableField(fill=FieldFill.UPDATE)注解可以實現(xiàn)在插入和更新時自動填充字段,比如創(chuàng)建時間和更新時間,使用@TableLogic注解標(biāo)識邏輯刪除字段2024-09-09

