之前寫(xiě)過(guò)文章記錄怎么在SpringBoot項(xiàng)目中簡(jiǎn)單使用定時(shí)任務(wù),不過(guò)由于要借助cron表達(dá)式且都提前定義好放在配置文件里,不能在項(xiàng)目運(yùn)行中動(dòng)態(tài)修改任務(wù)執(zhí)行時(shí)間,實(shí)在不太靈活。
經(jīng)過(guò)網(wǎng)上搜索學(xué)習(xí)后,特此記錄如何在SpringBoot項(xiàng)目中實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)。
因?yàn)橹皇且粋€(gè)demo,所以只引入了需要的依賴(lài):
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
啟動(dòng)類(lèi):
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("(*^▽^*)啟動(dòng)成功!!!(〃'▽'〃)"); } }
配置文件application.yml,只定義了服務(wù)端口:
server: port:8089
定時(shí)任務(wù)執(zhí)行時(shí)間配置文件:task-config.ini:
printTime.cron=0/10****?
定時(shí)任務(wù)執(zhí)行類(lèi):
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; /** *定時(shí)任務(wù) *@authorwl */ @Data @Slf4j @Component @PropertySource("classpath:/task-config.ini") publicclassScheduleTaskimplementsSchedulingConfigurer{ @Value("${printTime.cron}") privateStringcron; @Override publicvoidconfigureTasks(ScheduledTaskRegistrartaskRegistrar){ //動(dòng)態(tài)使用cron表達(dá)式設(shè)置循環(huán)間隔 taskRegistrar.addTriggerTask(newRunnable(){ @Override publicvoidrun(){ log.info("Current time:{}",LocalDateTime.now()); } },newTrigger(){ @Override publicDatenextExecutionTime(TriggerContexttriggerContext){ //使用CronTrigger觸發(fā)器,可動(dòng)態(tài)修改cron表達(dá)式來(lái)操作循環(huán)規(guī)則 CronTriggercronTrigger=newCronTrigger(cron); DatenextExecutionTime=cronTrigger.nextExecutionTime(triggerContext); returnnextExecutionTime; } }); } }
編寫(xiě)一個(gè)接口,使得可以通過(guò)調(diào)用接口動(dòng)態(tài)修改該定時(shí)任務(wù)的執(zhí)行時(shí)間:
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"; } }
啟動(dòng)項(xiàng)目,可以看到任務(wù)每10秒執(zhí)行一次:
訪問(wèn)接口,傳入請(qǐng)求參數(shù)cron表達(dá)式,將定時(shí)任務(wù)修改為15秒執(zhí)行一次:
可以看到任務(wù)變成了15秒執(zhí)行一次
除了上面的借助cron表達(dá)式的方法,還有另一種觸發(fā)器,區(qū)別于CronTrigger觸發(fā)器,該觸發(fā)器可隨意設(shè)置循環(huán)間隔時(shí)間,不像cron表達(dá)式只能定義小于等于間隔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; /** *定時(shí)任務(wù) *@authorwl */ @Data @Slf4j @Component @PropertySource("classpath:/task-config.ini") publicclassScheduleTaskimplementsSchedulingConfigurer{ @Value("${printTime.cron}") privateStringcron; privateLongtimer=10000L; @Override publicvoidconfigureTasks(ScheduledTaskRegistrartaskRegistrar){ //動(dòng)態(tài)使用cron表達(dá)式設(shè)置循環(huán)間隔 taskRegistrar.addTriggerTask(newRunnable(){ @Override publicvoidrun(){ log.info("Current time:{}",LocalDateTime.now()); } },newTrigger(){ @Override publicDatenextExecutionTime(TriggerContexttriggerContext){ //使用CronTrigger觸發(fā)器,可動(dòng)態(tài)修改cron表達(dá)式來(lái)操作循環(huán)規(guī)則 //CronTriggercronTrigger=newCronTrigger(cron); //DatenextExecutionTime=cronTrigger.nextExecutionTime(triggerContext); //使用不同的觸發(fā)器,為設(shè)置循環(huán)時(shí)間的關(guān)鍵,區(qū)別于CronTrigger觸發(fā)器,該觸發(fā)器可隨意設(shè)置循環(huán)間隔時(shí)間,單位為毫秒 PeriodicTriggerperiodicTrigger=newPeriodicTrigger(timer); DatenextExecutionTime=periodicTrigger.nextExecutionTime(triggerContext); returnnextExecutionTime; } }); } }
增加一個(gè)修改時(shí)間的接口:
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"; } }
測(cè)試結(jié)果:
基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶(hù)小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶(hù)、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能
項(xiàng)目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro
視頻教程:https://doc.iocoder.cn/video/
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶(hù)小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶(hù)、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能
項(xiàng)目地址:https://gitee.com/zhijiantianya/yudao-cloud
視頻教程:https://doc.iocoder.cn/video/
-
接口
+關(guān)注
關(guān)注
33文章
8997瀏覽量
153698 -
spring
+關(guān)注
關(guān)注
0文章
340瀏覽量
15061 -
SpringBoot
+關(guān)注
關(guān)注
0文章
175瀏覽量
397
原文標(biāo)題:SpringBoot 設(shè)置動(dòng)態(tài)定時(shí)任務(wù),千萬(wàn)別再寫(xiě)死了~
文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
定時(shí)任務(wù)的發(fā)展史是怎么樣的

SpringBoot如何實(shí)現(xiàn)動(dòng)態(tài)增刪啟停定時(shí)任務(wù)

Python定時(shí)任務(wù)的實(shí)現(xiàn)方式
解析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ù)(上)

SpringBoot-動(dòng)態(tài)定時(shí)任務(wù)調(diào)度

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

定時(shí)器如何實(shí)現(xiàn)定時(shí)任務(wù)
linux定時(shí)任務(wù)的用法總結(jié)

評(píng)論