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

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

提示:
- 在
Spring中我們通過@Scheduled注解來實(shí)現(xiàn)的定時(shí)任務(wù),底層也是通過ThreadPoolTaskScheduler來實(shí)現(xiàn)的??梢酝ㄟ^ScheduledAnnotationBeanPostProcessor類來查看。 ThreadPoolTaskScheduler的默認(rèn)線程數(shù)是1,這個(gè)需要根據(jù)實(shí)際的情況進(jìn)行修改。
三、代碼實(shí)現(xiàn)
此處只給出動(dòng)態(tài)注冊(cè)定時(shí)任務(wù)和取消的定時(shí)任務(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 {
// 動(dòng)態(tài)啟動(dòng)一個(gè)定時(shí)任務(wù)
log.info("注冊(cè)一個(gè)定時(shí)任務(wù):每隔1秒執(zhí)行一次");
scheduledFuture = register("* * * * * ?");
// 取消一個(gè)調(diào)度
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(5);
log.info("取消調(diào)度");
scheduledFuture.cancel(false);
log.info("取消結(jié)果:" + scheduledFuture.isCancelled());
log.info("重新注冊(cè)一個(gè)定時(shí)任務(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("定時(shí)任務(wù)下次執(zhí)行的時(shí)間為:[{}]", 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動(dòng)態(tài)添加定時(shí)任務(wù)的實(shí)現(xiàn)思路的文章就介紹到這了,更多相關(guān)Spring定時(shí)任務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java虛擬機(jī)JVM類加載機(jī)制原理(面試必問)
這篇文章主要介紹了面試當(dāng)中必會(huì)問到的java虛擬機(jī)JVM類加載機(jī)制,非常的詳細(xì),有需要的朋友可以借鑒參考下,歡迎多多交流討論2021-08-08
mybatis中關(guān)于type-aliases-package的使用
這篇文章主要介紹了mybatis中關(guān)于type-aliases-package的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
使用ScheduledThreadPoolExecutor踩過最痛的坑
這篇文章主要介紹了使用ScheduledThreadPoolExecutor踩過最痛的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
java 利用java反射機(jī)制動(dòng)態(tài)加載類的簡單實(shí)現(xiàn)
下面小編就為大家?guī)硪黄猨ava 利用java反射機(jī)制動(dòng)態(tài)加載類的簡單實(shí)現(xiàn)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-09-09
SpringCloud實(shí)戰(zhàn)之Feign聲明式服務(wù)調(diào)用
這篇文章主要介紹了SpringCloud實(shí)戰(zhàn)之Feign聲明式服務(wù)調(diào)用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05
Spring注解驅(qū)動(dòng)之BeanFactoryPostProcessor原理解析
這篇文章主要介紹了Spring注解驅(qū)動(dòng)之BeanFactoryPostProcessor原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09

