之前寫過文章記錄怎么在SpringBoot項目中簡單使用定時任務,不過由于要借助cron表達式且都提前定義好放在配置文件里,不能在項目運行中動態(tài)修改任務執(zhí)行時間,實在不太靈活。
經(jīng)過網(wǎng)上搜索學習后,特此記錄如何在SpringBoot項目中實現(xiàn)動態(tài)定時任務。
因為只是一個demo,所以只引入了需要的依賴:
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-log4j2 true org.springframework.boot spring-boot-starter-validation org.projectlombok lombok true
啟動類:
packagecom.wl.demo; importorg.springframework.boot.SpringApplication; importorg.springframework.boot.autoconfigure.SpringBootApplication; importorg.springframework.scheduling.annotation.EnableScheduling; /** *@authorwl */ @EnableScheduling @SpringBootApplication publicclassDemoApplication{ publicstaticvoidmain(String[]args){ SpringApplication.run(DemoApplication.class,args); System.out.println("(*^▽^*)啟動成功!!!(〃'▽'〃)"); } }
配置文件application.yml,只定義了服務端口:
server: port:8089
定時任務執(zhí)行時間配置文件:task-config.ini:
printTime.cron=0/10****?
定時任務執(zhí)行類:
packagecom.wl.demo.task; importlombok.Data; importlombok.extern.slf4j.Slf4j; importorg.springframework.beans.factory.annotation.Value; importorg.springframework.context.annotation.PropertySource; importorg.springframework.scheduling.Trigger; importorg.springframework.scheduling.TriggerContext; importorg.springframework.scheduling.annotation.SchedulingConfigurer; importorg.springframework.scheduling.config.ScheduledTaskRegistrar; importorg.springframework.scheduling.support.CronTrigger; importorg.springframework.stereotype.Component; importjava.time.LocalDateTime; importjava.util.Date; /** *定時任務 *@authorwl */ @Data @Slf4j @Component @PropertySource("classpath:/task-config.ini") publicclassScheduleTaskimplementsSchedulingConfigurer{ @Value("${printTime.cron}") privateStringcron; @Override publicvoidconfigureTasks(ScheduledTaskRegistrartaskRegistrar){ //動態(tài)使用cron表達式設置循環(huán)間隔 taskRegistrar.addTriggerTask(newRunnable(){ @Override publicvoidrun(){ log.info("Current time:{}",LocalDateTime.now()); } },newTrigger(){ @Override publicDatenextExecutionTime(TriggerContexttriggerContext){ //使用CronTrigger觸發(fā)器,可動態(tài)修改cron表達式來操作循環(huán)規(guī)則 CronTriggercronTrigger=newCronTrigger(cron); DatenextExecutionTime=cronTrigger.nextExecutionTime(triggerContext); returnnextExecutionTime; } }); } }
編寫一個接口,使得可以通過調(diào)用接口動態(tài)修改該定時任務的執(zhí)行時間:
packagecom.wl.demo.controller; importcom.wl.demo.task.ScheduleTask; importlombok.extern.slf4j.Slf4j; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.web.bind.annotation.GetMapping; importorg.springframework.web.bind.annotation.RequestMapping; importorg.springframework.web.bind.annotation.RestController; /** *@authorwl */ @Slf4j @RestController @RequestMapping("/test") publicclassTestController{ privatefinalScheduleTaskscheduleTask; @Autowired publicTestController(ScheduleTaskscheduleTask){ this.scheduleTask=scheduleTask; } @GetMapping("/updateCron") publicStringupdateCron(Stringcron){ log.info("newcron:{}",cron); scheduleTask.setCron(cron); return"ok"; } }
啟動項目,可以看到任務每10秒執(zhí)行一次:

訪問接口,傳入請求參數(shù)cron表達式,將定時任務修改為15秒執(zhí)行一次:

可以看到任務變成了15秒執(zhí)行一次

除了上面的借助cron表達式的方法,還有另一種觸發(fā)器,區(qū)別于CronTrigger觸發(fā)器,該觸發(fā)器可隨意設置循環(huán)間隔時間,不像cron表達式只能定義小于等于間隔59秒。
packagecom.wl.demo.task;
importlombok.Data;
importlombok.extern.slf4j.Slf4j;
importorg.springframework.beans.factory.annotation.Value;
importorg.springframework.context.annotation.PropertySource;
importorg.springframework.scheduling.Trigger;
importorg.springframework.scheduling.TriggerContext;
importorg.springframework.scheduling.annotation.SchedulingConfigurer;
importorg.springframework.scheduling.config.ScheduledTaskRegistrar;
importorg.springframework.scheduling.support.CronTrigger;
importorg.springframework.scheduling.support.PeriodicTrigger;
importorg.springframework.stereotype.Component;
importjava.time.LocalDateTime;
importjava.util.Date;
/**
*定時任務
*@authorwl
*/
@Data
@Slf4j
@Component
@PropertySource("classpath:/task-config.ini")
publicclassScheduleTaskimplementsSchedulingConfigurer{
@Value("${printTime.cron}")
privateStringcron;
privateLongtimer=10000L;
@Override
publicvoidconfigureTasks(ScheduledTaskRegistrartaskRegistrar){
//動態(tài)使用cron表達式設置循環(huán)間隔
taskRegistrar.addTriggerTask(newRunnable(){
@Override
publicvoidrun(){
log.info("Current time:{}",LocalDateTime.now());
}
},newTrigger(){
@Override
publicDatenextExecutionTime(TriggerContexttriggerContext){
//使用CronTrigger觸發(fā)器,可動態(tài)修改cron表達式來操作循環(huán)規(guī)則
//CronTriggercronTrigger=newCronTrigger(cron);
//DatenextExecutionTime=cronTrigger.nextExecutionTime(triggerContext);
//使用不同的觸發(fā)器,為設置循環(huán)時間的關鍵,區(qū)別于CronTrigger觸發(fā)器,該觸發(fā)器可隨意設置循環(huán)間隔時間,單位為毫秒
PeriodicTriggerperiodicTrigger=newPeriodicTrigger(timer);
DatenextExecutionTime=periodicTrigger.nextExecutionTime(triggerContext);
returnnextExecutionTime;
}
});
}
}
增加一個修改時間的接口:
packagecom.wl.demo.controller;
importcom.wl.demo.task.ScheduleTask;
importlombok.extern.slf4j.Slf4j;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.web.bind.annotation.GetMapping;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.RestController;
/**
*@authorwl
*/
@Slf4j
@RestController
@RequestMapping("/test")
publicclassTestController{
privatefinalScheduleTaskscheduleTask;
@Autowired
publicTestController(ScheduleTaskscheduleTask){
this.scheduleTask=scheduleTask;
}
@GetMapping("/updateCron")
publicStringupdateCron(Stringcron){
log.info("newcron:{}",cron);
scheduleTask.setCron(cron);
return"ok";
}
@GetMapping("/updateTimer")
publicStringupdateTimer(Longtimer){
log.info("newtimer:{}",timer);
scheduleTask.setTimer(timer);
return"ok";
}
}
測試結果:

基于 Spring Boot + MyBatis Plus + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權限、多租戶、數(shù)據(jù)權限、工作流、三方登錄、支付、短信、商城等功能
項目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro
視頻教程:https://doc.iocoder.cn/video/
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權限、多租戶、數(shù)據(jù)權限、工作流、三方登錄、支付、短信、商城等功能
項目地址:https://gitee.com/zhijiantianya/yudao-cloud
視頻教程:https://doc.iocoder.cn/video/
-
接口
+關注
關注
33文章
9437瀏覽量
156067 -
spring
+關注
關注
0文章
341瀏覽量
15759 -
SpringBoot
+關注
關注
0文章
177瀏覽量
622
原文標題:SpringBoot 設置動態(tài)定時任務,千萬別再寫死了~
文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
定時任務的發(fā)展史是怎么樣的
SpringBoot如何實現(xiàn)動態(tài)增刪啟停定時任務
Python定時任務的實現(xiàn)方式
解析Golang定時任務庫gron設計和原理
xxl-job任務調(diào)度中間件解決定時任務的調(diào)度問題
求一種SpringBoot定時任務動態(tài)管理通用解決方案
SpringBoot如何實現(xiàn)定時任務(下)
SpringBoot如何實現(xiàn)定時任務(上)

如何在SpringBoot項目中實現(xiàn)動態(tài)定時任務
評論