一、背景
在工作中,有些時候我們有些定時任務的執行可能是需要動態修改的,比如: 生成報表,有些項目配置每天的8點生成,有些項目配置每天的10點生成,像這種動態的任務執行時間,在不考慮分布式執行的情況下,我們可以
使用 spring task
來簡單的實現。
二、需求和實現思路
1、能夠動態的添加一個定時任務。
在spring
中存在一個類threadpooltaskscheduler
,它可以實現根據一個cron表達式
來調度一個任務,并返回一個scheduledfuture
對象。
2、能夠取消定時任務的執行。
通過調用上一步的scheduledfuture
的cancel
方法,就可以將這個任務取消。
3、動態的修改任務執行的時間。
先取消任務。然后在重新注冊一個任務。
4、獲取定時任務執行的異常
threadpooltaskscheduler類中有一個設置errorhandler
的方法,給自己實現的errorhandler即可。
提示:
-
在
spring
中我們通過@scheduled
注解來實現的定時任務,底層也是通過threadpooltaskscheduler
來實現的。可以通過scheduledannotationbeanpostprocessor
類來查看。 -
threadpooltaskscheduler
的默認線程數是1,這個需要根據實際的情況進行修改。
三、代碼實現
此處只給出動態注冊定時任務和取消的定時任務的代碼。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
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 { // 動態啟動一個定時任務 log.info( "注冊一個定時任務:每隔1秒執行一次" ); scheduledfuture = register( "* * * * * ?" ); // 取消一個調度 new thread(() -> { try { timeunit.seconds.sleep( 5 ); log.info( "取消調度" ); scheduledfuture.cancel( false ); log.info( "取消結果:" + scheduledfuture.iscancelled()); log.info( "重新注冊一個定時任務:每隔2秒執行一次" ); 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( "定時任務下次執行的時間為:[{}]" , nextexectime.format(datetimeformatter.ofpattern( "yyyy-mm-dd hh:mm:ss" ))); } return taskscheduler.schedule( new runnable() { @override public void run() { log.info( "我執行了" ); } }, new crontrigger(cron)); } } |
四、執行結果
五、完整代碼
https://gitee.com/huan1993/spring-cloud-parent/tree/master/springboot/springboot-task
到此這篇關于spring動態添加定時任務的實現思路的文章就介紹到這了,更多相關spring定時任務內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/fu_huo_1993/article/details/118583494