一、業(yè)務(wù)場(chǎng)景
先說(shuō)業(yè)務(wù)場(chǎng)景,根據(jù)用戶輸入的cron表達(dá)式進(jìn)行定時(shí)調(diào)度,舉個(gè)例子:如圖
根據(jù)用戶輸入的參數(shù),生成表達(dá)式,然后定時(shí)去執(zhí)行相應(yīng)的業(yè)務(wù)邏輯。
二、Controller層(不是重點(diǎn))
domain類
@TableName("sys_schedule")
@Data
public class Schedule {
private static final long serialVersionUID = 1L;
/**
* 主鍵ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 類型: 時(shí)間, 周, 日
*/
@TableField("type")
private Integer type;
/**
* time 時(shí)間
*/
@TableField("day_time")
private String dayTime;
/**
* time 周
*/
@TableField("weekday")
private String weekday;
/**
* time 日
*/
@TableField("monthday")
private String monthday;
/**
* 選中狀態(tài)
*/
@TableField("status")
private Integer status;
@TableField("cron")
private String cron;
@Override
public String toString() {
return "Schedule{" +
"id=" + id +
", type=" + type +
", dayTime='" + dayTime + '\\'' +
", weekday='" + weekday + '\\'' +
", monthday='" + monthday + '\\'' +
", status=" + status +
", cron='" + cron + '\\'' +
'}';
}
}
controller方法
@Autowired
private ScheduleService scheduleService;
@PutMapping("/editItem")
@ResponseBody
public ResponseData editItem(Schedule schedule) {
//ResponseData自己封裝的響應(yīng)結(jié)果
//param是你前端傳的,包含你的數(shù)據(jù),如cron表達(dá)式
this.scheduleService.update(schedule);
return ResponseData.success();
}
三、Service層
接口層
public interface ScheduleService {
/**
* 更新
* @Date 2020-12-25
*/
void update(Schedule param);
/**
* 業(yè)務(wù)處理
* @Date 2020-12-25
*/
void work();
}
實(shí)現(xiàn)層
@Service
public class ScheduleServiceImpl implements ScheduleService {
@Override
public void update(Schedule param) {
//這里簡(jiǎn)化了我自己的業(yè)務(wù)邏輯代碼,根據(jù)公司自己需要來(lái)寫即可
//業(yè)務(wù)邏輯代碼
//思路就是:更新數(shù)據(jù)庫(kù)的cron,類型等值,然后交給下面的定時(shí)工具類走定時(shí)方法
this.scheduleMapper.updateById(param);
String cron = param.getCron();
//this就是你的業(yè)務(wù)執(zhí)行service, 這里就是scheduleService
ScheduleUtil.reset(new ScheduleTask(param.getId().toString(), this, null), cron);
}
@Override
public void work() {
//抓取數(shù)據(jù)的代碼
System.out.println("業(yè)務(wù)代碼執(zhí)行。。。");
}
}
四、定時(shí)工具類
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
public class ScheduleUtil {
private static ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
private static Map<String, ScheduledFuture?> scheduledFutureMap = new HashMap<>();
static {
threadPoolTaskScheduler.initialize();
System.out.println("定時(shí)任務(wù)線程池啟動(dòng)");
}
/**
* 啟動(dòng)
*
* @param scheduleTask 定時(shí)任務(wù)
* @param corn 執(zhí)行時(shí)間表達(dá)式
*/
public static boolean start(ScheduleTask scheduleTask, String corn) {
System.out.println("啟動(dòng)定時(shí)任務(wù)線程 taskId " + scheduleTask.getId());
ScheduledFuture? scheduledFuture = threadPoolTaskScheduler
.schedule(scheduleTask, new CronTrigger(corn));
scheduledFutureMap.put(scheduleTask.getId(), scheduledFuture);
return true;
}
/**
* 取消
*
* @param scheduleTask 定時(shí)任務(wù)
*/
public static boolean cancel(ScheduleTask scheduleTask) {
System.out.println("關(guān)閉定時(shí)任務(wù)線程 taskId " + scheduleTask.getId());
ScheduledFuture? scheduledFuture = scheduledFutureMap.get(scheduleTask.getId());
if (scheduledFuture != null && !scheduledFuture.isCancelled()) {
scheduledFuture.cancel(false);
}
scheduledFutureMap.remove(scheduleTask.getId());
return true;
}
/**
* 修改
*
* @param scheduleTask 定時(shí)任務(wù)
* @param corn 執(zhí)行時(shí)間表達(dá)式
*/
public static boolean reset(ScheduleTask scheduleTask, String corn) {
//先取消定時(shí)任務(wù)
cancel(scheduleTask);
//然后啟動(dòng)新的定時(shí)任務(wù)
start(scheduleTask, corn);
return true;
}
}
五、工作線程
public class ScheduleTask implements Runnable {
private static final int TIMEOUT = 30000;
private String id;
private ScheduleService service;
public String getId() {
return id;
}
/**
* @param id 任務(wù)ID
* @param service 業(yè)務(wù)類
* @param keyword 關(guān)鍵字參數(shù)
*/
public ScheduleTask(String id, ScheduleService service) {
this.id = id;
this.service = service;
}
@Override
public void run() {
//你自己的業(yè)務(wù)邏輯
service.work();
}
}
到這里結(jié)束了,這里主要是根據(jù)前臺(tái)傳的時(shí)間,進(jìn)行生成cron,入庫(kù),執(zhí)行定時(shí)任務(wù)。但是有一個(gè)問(wèn)題,就是如果項(xiàng)目重啟了的話,那么定時(shí)類那是無(wú)法加載到cron表達(dá)式的。那么接下來(lái),加一個(gè)項(xiàng)目啟動(dòng)時(shí),把數(shù)據(jù)庫(kù)里的cron表達(dá)式重新灌入到定時(shí)類就可以。代碼如下:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 項(xiàng)目啟動(dòng)時(shí),加載
* @Date: 2020/12/25:16:00
**/
@Component
@Order(1)
public class initLineRunner implements CommandLineRunner {
@Autowired
private ScheduleService scheduleService;
@Override
public void run(String... args) throws Exception {
System.out.println("init ........... ");
//這里就是獲取你數(shù)據(jù)庫(kù)里的那個(gè)cron表達(dá)式
Schedule param = scheduleService.get();
String cron = param.getCron();
ScheduleUtil.reset(new ScheduleTask(param.getId().toString(), scheduleService, null), cron);
}
}
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。
本文鏈接:
https://blog.csdn.net/bbscz007/article/details/111695289
-
代碼
+關(guān)注
關(guān)注
30文章
4886瀏覽量
70248 -
spring
+關(guān)注
關(guān)注
0文章
340瀏覽量
14878 -
SpringBoot
+關(guān)注
關(guān)注
0文章
175瀏覽量
318
發(fā)布評(píng)論請(qǐng)先 登錄
Linux系統(tǒng)定時(shí)任務(wù)Crond
OPC 實(shí)時(shí)任務(wù)系統(tǒng)動(dòng)態(tài)調(diào)度算法的研究與設(shè)計(jì)The Stud
SpringBoot如何實(shí)現(xiàn)動(dòng)態(tài)增刪啟停定時(shí)任務(wù)

Python定時(shí)任務(wù)的實(shí)現(xiàn)方式
如何在SpringBoot項(xiàng)目中實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)
解析Golang定時(shí)任務(wù)庫(kù)gron設(shè)計(jì)和原理
xxl-job任務(wù)調(diào)度中間件解決定時(shí)任務(wù)的調(diào)度問(wèn)題
求一種SpringBoot定時(shí)任務(wù)動(dòng)態(tài)管理通用解決方案
SpringBoot如何實(shí)現(xiàn)定時(shí)任務(wù)(下)

SpringBoot如何實(shí)現(xiàn)定時(shí)任務(wù)(上)

在Spring Boot中如何使用定時(shí)任務(wù)
如何動(dòng)態(tài)添加修改刪除定時(shí)任務(wù)?
Linux如何使用cron進(jìn)行定時(shí)任務(wù)的操作
python定時(shí)任務(wù)實(shí)踐

linux定時(shí)任務(wù)的用法總結(jié)

評(píng)論