Springboot自带Schedule通常使用注解的方式配置一个任务,当程序运行时需要动态创建、修改、删除、启动、任务时就需要操作TaskScheduler接口了。下面做一个简单的实现
pom
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.10</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Application类
package zone.cong.dynamicscheduledtask;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling // 开启Schedule
public class DynamicScheduledTaskApplication {
public static void main(String[] args) {
SpringApplication.run(DynamicScheduledTaskApplication.class, args);
}
}
实体类
package zone.cong.dynamicscheduledtask.entity;
import java.time.LocalDateTime;
import java.util.concurrent.ScheduledFuture;
public class ScheduledTask implements Runnable {
private final String id;
private String cron;
private String content;
private ScheduledFuture<?> future;
private LocalDateTime lastExecTime;
public ScheduledTask(String cron, String content) {
this.id = String.valueOf(System.nanoTime());
this.cron = cron;
this.content = content;
}
public String getId() {
return id;
}
public String getCron() {
return cron;
}
public void setCron(String cron) {
this.cron = cron;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public ScheduledFuture<?> getFuture() {
return future;
}
public LocalDateTime getLastExecTime() {
return lastExecTime;
}
public void setFuture(ScheduledFuture<?> future) {
this.future = future;
}
public void setLastExecTime(LocalDateTime lastExecTime) {
this.lastExecTime = lastExecTime;
}
@Override
public void run() {
System.out.println(content);
setLastExecTime(LocalDateTime.now());
}
}
package zone.cong.dynamicscheduledtask.entity;
public class ScheduleRequest {
private String cron;
private String content;
public String getCron() {
return cron;
}
public void setCron(String cron) {
this.cron = cron;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
package zone.cong.dynamicscheduledtask.entity;
public class TaskInfo {
private final String id;
private final String cron;
private final String content;
private final boolean isRunning;
private final String lastExecTime;
public TaskInfo(String id, String cron, String content, boolean isRunning, String lastExecTime) {
this.id = id;
this.cron = cron;
this.content = content;
this.isRunning = isRunning;
this.lastExecTime = lastExecTime;
}
public String getId() {
return id;
}
public String getCron() {
return cron;
}
public String getContent() {
return content;
}
public boolean isRunning() {
return isRunning;
}
public String getLastExecTime() {
return lastExecTime;
}
}
controller
package zone.cong.dynamicscheduledtask.controller;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import zone.cong.dynamicscheduledtask.entity.ScheduleRequest;
import zone.cong.dynamicscheduledtask.entity.ScheduledTask;
import zone.cong.dynamicscheduledtask.entity.TaskInfo;
@RestController
public class ScheduledTaskController {
@Autowired
private TaskScheduler scheduler;
// 存储任务信息,key 为任务 ID,value 为任务信息
private Map<String, ScheduledTask> tasks = new ConcurrentHashMap<>();
@GetMapping("/tasks")
public List<TaskInfo> listTasks() {
List<TaskInfo> result = new ArrayList<>();
for (ScheduledTask task : tasks.values()) {
boolean isRunning = task.getFuture() != null && !task.getFuture().isCancelled();
LocalDateTime lastExecTime = task.getLastExecTime();
String lastExecTimeStr = lastExecTime != null ? lastExecTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) : "";
result.add(new TaskInfo(task.getId(), task.getCron(), task.getContent(), isRunning, lastExecTimeStr));
}
return result;
}
@PostMapping("/tasks")
public void scheduleTask(@RequestBody ScheduleRequest request) {
ScheduledTask task = new ScheduledTask(request.getCron(), request.getContent());
ScheduledFuture<?> future = scheduler.schedule(task, new CronTrigger(request.getCron()));
task.setFuture(future);
tasks.put(task.getId(), task);
}
@DeleteMapping("/tasks/{id}")
public void cancelTask(@PathVariable String id) {
ScheduledTask task = tasks.remove(id);
if (task != null) {
task.getFuture().cancel(true);
}
}
@PostMapping("/tasks/{id}")
public void updateTask(@PathVariable String id, @RequestBody ScheduleRequest request) {
ScheduledTask task = tasks.remove(id);
if (task != null) {
task.setCron(request.getCron());
task.setContent(request.getContent());
task.getFuture().cancel(true);
ScheduledFuture<?> future = scheduler.schedule(task, new CronTrigger(request.getCron()));
task.setFuture(future);
tasks.put(task.getId(), task);
}
}
@PostMapping("/tasks/{id}/start")
public void startTask(@PathVariable String id) {
ScheduledTask task = tasks.get(id);
if (task != null && task.getFuture() == null) {
LocalDateTime lastExecTime = LocalDateTime.now();
ScheduledFuture<?> future = scheduler.schedule(task, new CronTrigger(task.getCron()));
task.setFuture(future);
task.setLastExecTime(lastExecTime);
}
}
@PostMapping("/tasks/{id}/stop")
public void stopTask(@PathVariable String id) {
ScheduledTask task = tasks.get(id);
if (task != null && task.getFuture() != null) {
task.getFuture().cancel(true);
task.setFuture(null);
}
}
@PostMapping("/tasks/startAll")
public void startAllTasks() {
for (ScheduledTask task : tasks.values()) {
if (task.getFuture() == null) {
LocalDateTime lastExecTime = LocalDateTime.now();
ScheduledFuture<?> future = scheduler.schedule(task, new CronTrigger(task.getCron()));
task.setFuture(future);
task.setLastExecTime(lastExecTime);
}
}
}
@PostMapping("/tasks/stopAll")
public void stopAllTasks() {
for (ScheduledTask task : tasks.values()) {
if (task.getFuture() != null) {
task.getFuture().cancel(true);
task.setFuture(null);
}
}
}
}
评论区