SpringBoot設(shè)置動(dòng)態(tài)定時(shí)任務(wù)的方法詳解
之前寫過文章記錄怎么在SpringBoot項(xiàng)目中簡(jiǎn)單使用定時(shí)任務(wù),不過由于要借助cron表達(dá)式且都提前定義好放在配置文件里,不能在項(xiàng)目運(yùn)行中動(dòng)態(tài)修改任務(wù)執(zhí)行時(shí)間,實(shí)在不太靈活。
經(jīng)過網(wǎng)上搜索學(xué)習(xí)后,特此記錄如何在SpringBoot項(xiàng)目中實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)。
因?yàn)橹皇且粋€(gè)demo,所以只引入了需要的依賴:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<optional>true</optional>
</dependency>
<!-- spring boot 2.3版本后,如果需要使用校驗(yàn),需手動(dòng)導(dǎo)入validation包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>啟動(dòng)類:
package com.wl.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @author wl
* @date 2022/3/22
*/
@EnableScheduling
@SpringBootApplication
public class DemoApplication {
public static void main(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í)行類:
package com.wl.demo.task;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 定時(shí)任務(wù)
* @author wl
* @date 2022/3/22
*/
@Data
@Slf4j
@Component
@PropertySource("classpath:/task-config.ini")
public class ScheduleTask implements SchedulingConfigurer {
@Value("${printTime.cron}")
private String cron;
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
// 動(dòng)態(tài)使用cron表達(dá)式設(shè)置循環(huán)間隔
taskRegistrar.addTriggerTask(new Runnable() {
@Override
public void run() {
log.info("Current time: {}", LocalDateTime.now());
}
}, new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
// 使用CronTrigger觸發(fā)器,可動(dòng)態(tài)修改cron表達(dá)式來操作循環(huán)規(guī)則
CronTrigger cronTrigger = new CronTrigger(cron);
Date nextExecutionTime = cronTrigger.nextExecutionTime(triggerContext);
return nextExecutionTime;
}
});
}
}編寫一個(gè)接口,使得可以通過調(diào)用接口動(dòng)態(tài)修改該定時(shí)任務(wù)的執(zhí)行時(shí)間:
package com.wl.demo.controller;
import com.wl.demo.task.ScheduleTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author wl
* @date 2022/3/22
*/
@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
private final ScheduleTask scheduleTask;
@Autowired
public TestController(ScheduleTask scheduleTask) {
this.scheduleTask = scheduleTask;
}
@GetMapping("/updateCron")
public String updateCron(String cron) {
log.info("new cron :{}", cron);
scheduleTask.setCron(cron);
return "ok";
}
}啟動(dòng)項(xiàng)目,可以看到任務(wù)每10秒執(zhí)行一次:

訪問接口,傳入請(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秒。
package com.wl.demo.task;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 定時(shí)任務(wù)
* @author wl
* @date 2022/3/22
*/
@Data
@Slf4j
@Component
@PropertySource("classpath:/task-config.ini")
public class ScheduleTask implements SchedulingConfigurer {
@Value("${printTime.cron}")
private String cron;
private Long timer = 10000L;
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
// 動(dòng)態(tài)使用cron表達(dá)式設(shè)置循環(huán)間隔
taskRegistrar.addTriggerTask(new Runnable() {
@Override
public void run() {
log.info("Current time: {}", LocalDateTime.now());
}
}, new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
// 使用CronTrigger觸發(fā)器,可動(dòng)態(tài)修改cron表達(dá)式來操作循環(huán)規(guī)則
// CronTrigger cronTrigger = new CronTrigger(cron);
// Date nextExecutionTime = cronTrigger.nextExecutionTime(triggerContext);
// 使用不同的觸發(fā)器,為設(shè)置循環(huán)時(shí)間的關(guān)鍵,區(qū)別于CronTrigger觸發(fā)器,該觸發(fā)器可隨意設(shè)置循環(huán)間隔時(shí)間,單位為毫秒
PeriodicTrigger periodicTrigger = new PeriodicTrigger(timer);
Date nextExecutionTime = periodicTrigger.nextExecutionTime(triggerContext);
return nextExecutionTime;
}
});
}
}增加一個(gè)修改時(shí)間的接口:
package com.wl.demo.controller;
import com.wl.demo.task.ScheduleTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author wl
* @date 2022/3/22
*/
@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
private final ScheduleTask scheduleTask;
@Autowired
public TestController(ScheduleTask scheduleTask) {
this.scheduleTask = scheduleTask;
}
@GetMapping("/updateCron")
public String updateCron(String cron) {
log.info("new cron :{}", cron);
scheduleTask.setCron(cron);
return "ok";
}
@GetMapping("/updateTimer")
public String updateTimer(Long timer) {
log.info("new timer :{}", timer);
scheduleTask.setTimer(timer);
return "ok";
}
}測(cè)試結(jié)果:

到此這篇關(guān)于SpringBoot設(shè)置動(dòng)態(tài)定時(shí)任務(wù)的方法詳解的文章就介紹到這了,更多相關(guān)SpringBoot設(shè)置動(dòng)態(tài)定時(shí)任務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring*.xml配置文件明文加密的實(shí)現(xiàn)
這篇文章主要介紹了spring*.xml配置文件明文加密的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
Java使用Lambda表達(dá)式查找list集合中是否包含某值問題
Java使用Lambda表達(dá)式查找list集合中是否包含某值的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
解決 Spring RestTemplate post傳遞參數(shù)時(shí)報(bào)錯(cuò)問題
本文詳解說明了RestTemplate post傳遞參數(shù)時(shí)報(bào)錯(cuò)的問題及其原由,需要的朋友可以參考下2020-02-02
MyBatis實(shí)現(xiàn)插入大量數(shù)據(jù)方法詳解
最近在公司項(xiàng)目開發(fā)中遇到批量數(shù)據(jù)插入或者更新,下面這篇文章主要給大家介紹了關(guān)于MyBatis實(shí)現(xiàn)批量插入的相關(guān)資料,需要的朋友可以參考下2022-11-11
SpringBoot項(xiàng)目配置明文密碼泄露問題的處理方式
這篇文章主要介紹了SpringBoot項(xiàng)目配置明文密碼泄露問題的處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06

