之前寫(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,所以只引入了需要的依賴:
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)類:
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í)行類:
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) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(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) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能
項(xiàng)目地址:https://gitee.com/zhijiantianya/yudao-cloud
視頻教程:https://doc.iocoder.cn/video/
-
接口
+關(guān)注
關(guān)注
33文章
8598瀏覽量
151152 -
spring
+關(guān)注
關(guān)注
0文章
340瀏覽量
14343 -
SpringBoot
+關(guān)注
關(guān)注
0文章
173瀏覽量
179
原文標(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)先 登錄
相關(guān)推薦
評(píng)論