当前位置: 首页 > news >正文

【SpringBoot】@Scheduled是静态配置,是我想改时间,但又不想引入其他组件,还有什么方案么?

TaskScheduler动态定时任务

定时任务的编写,在 Spring 里常见的两种方式:

  1. @Scheduled 注解 → 静态配置,启动时就确定了,不能动态改。

  2. TaskScheduler → 可以在运行时动态添加 / 修改 / 取消任务。

示例代码

任务可以存储在数据库,这里用map模拟。

import lombok.Data;@Data
public class TaskRequest {private String taskId;private String cron;private String beanName;   // Bean 名称private String methodName; // 方法名
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;@Configuration
public class SchedulerConfig {@Beanpublic ThreadPoolTaskScheduler taskScheduler() {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.setPoolSize(5);scheduler.setThreadNamePrefix("dynamic-task-");scheduler.initialize();return scheduler;}
}
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;@Component
public class DynamicTaskManager {private final TaskScheduler taskScheduler;private final ApplicationContext applicationContext;private final Map<String, ScheduledFuture<?>> taskMap = new ConcurrentHashMap<>();public DynamicTaskManager(TaskScheduler taskScheduler, ApplicationContext applicationContext) {this.taskScheduler = taskScheduler;this.applicationContext = applicationContext;}// 添加任务public void addTask(String taskId, String cron, String beanName, String methodName) {if (taskMap.containsKey(taskId)) {throw new IllegalArgumentException("任务已存在: " + taskId);}Runnable task = () -> {try {Object bean = applicationContext.getBean(beanName);Method method = bean.getClass().getMethod(methodName);method.invoke(bean);} catch (Exception e) {e.printStackTrace();}};ScheduledFuture<?> future = taskScheduler.schedule(task, new CronTrigger(cron));taskMap.put(taskId, future);}public void removeTask(String taskId) {ScheduledFuture<?> future = taskMap.remove(taskId);if (future != null) {future.cancel(true);}}public void updateTask(String taskId, String cron, String beanName, String methodName) {removeTask(taskId);addTask(taskId, cron, beanName, methodName);}public boolean hasTask(String taskId) {return taskMap.containsKey(taskId);}public Map<String, Boolean> listTasks() {Map<String, Boolean> result = new ConcurrentHashMap<>();taskMap.forEach((id, f) -> result.put(id, !f.isCancelled()));return result;}
}
import org.springframework.stereotype.Component;@Component("myTaskBean")
public class MyTaskMethods {public void sendEmail() {System.out.println("发送邮件任务执行了:" + new java.util.Date());}public void cleanCache() {System.out.println("清理缓存任务执行了:" + new java.util.Date());}public void generateReport() {System.out.println("生成报表任务执行了:" + new java.util.Date());}
}

import org.springframework.web.bind.annotation.*;import java.util.Map;@RestController
@RequestMapping("/tasks")
public class TaskController {private final DynamicTaskManager taskManager;public TaskController(DynamicTaskManager taskManager) {this.taskManager = taskManager;}@PostMapping("/add")public String addTask(@RequestBody TaskRequest request) {taskManager.addTask(request.getTaskId(), request.getCron(),request.getBeanName(), request.getMethodName());return "任务添加成功: " + request.getTaskId();}@PostMapping("/update")public String updateTask(@RequestBody TaskRequest request) {taskManager.updateTask(request.getTaskId(), request.getCron(),request.getBeanName(), request.getMethodName());return "任务更新成功: " + request.getTaskId();}@DeleteMapping("/remove/{taskId}")public String removeTask(@PathVariable String taskId) {taskManager.removeTask(taskId);return "任务删除成功: " + taskId;}@GetMapping("/list")public Map<String, Boolean> listTasks() {return taskManager.listTasks();}
}

调试示例代码

添加任务(调用 MyTaskMethods.sendEmail(),每 5 秒执行一次)

POST http://localhost:8080/tasks/add
Content-Type: application/json{"taskId": "emailTask","cron": "*/5 * * * * *","beanName": "myTaskBean","methodName": "sendEmail"
}

更新任务(改成调用 cleanCache(),每 10 秒执行一次)

POST http://localhost:8080/tasks/update
Content-Type: application/json{"taskId": "emailTask","cron": "*/10 * * * * *","beanName": "myTaskBean","methodName": "cleanCache"
}

删除任务

DELETE http://localhost:8080/tasks/remove/emailTask
http://www.dtcms.com/a/423529.html

相关文章:

  • ip做网站地址电商平面设计师
  • C语言内存布局:虚拟地址空间详解
  • 南昌比较好的网站设计白银市建设网站
  • Redis:高性能内存数据库的六大核心优势
  • Qt 程序包括Qt Creator 无法使用fcitx 输入法的解决办法
  • 【题解】洛谷 P4051 [JSOI2007] 字符加密 [后缀数组]
  • 免费 网站建设火车头 wordpress接口
  • 【MYSQL 】SQL 行列转换实战:如何用 CASE WHEN 与 SUM/MAX 重塑部门表
  • 网站申请支付宝支付网站关键词选取的方法
  • 最新版谷歌浏览器Axure插件(免翻墙)
  • 网站加载特效代码开源镜像网站开发
  • 虚拟串口工具vspd
  • 从入门到精通【Redis】理解Redis事务
  • Android16 wifi启动后自动连接的第一个wifi分析和修改
  • 【C++STL :vector类 (一) 】详解vector类的使用层vector实践:算法题练习
  • 做淘宝用那些网站发货如何进行电子商务网站推广
  • 语言是火,视觉是光:论两种智能信号的宿命与人机交互的未来
  • Java应用实例:三角形判断(向量叉积、海伦公式)、分数序列求和
  • Go Modules 包管理 (Go 模块)
  • Go基础(⑦实例和依赖注入)
  • 网站建设绩效考核方案ppt网页开发背景与意义
  • 【数据结构】基础知识
  • Fluttercon EU 2025 :Let‘s go far with Flutter
  • go-commons/stringutils 与标准库 strings 对比
  • 长春网站推广方式seo综合查询国产
  • 探索3D空间的视觉基础模型系列
  • 自建营销型企业网站怎么建设公益网站
  • C# 基于halcon的视觉工作流-章40-OCR训练识别
  • OCR API-智能文字识别技术,从“手动录入”到“智慧识别”的跨越
  • 收到网站代码后怎么做设计素材模板