基于上一篇动态多定时任务,想到貌似可以将其扩展一下,于是有了这篇。
上一篇链接
完整代码:
实体类:
Java
@Data
public class DemoTask {
private String id;
//0 fixed 1 cron
private int type;
//fixed required
private int seconds;
//cron required
private String cron;
private String methodName;
private String input;
}
核心处理类:
Java
@Slf4j
@Component
public class DemoTaskService {
@Autowired
private TaskScheduler taskScheduler;
@Autowired
private ApplicationContext applicationContext;
private Map<String, ScheduledFuture<?>> futureMap = new ConcurrentHashMap<>();
/**
* 启动定时任务
*/
public void startTask(DemoTask task) {
stopTask(task.getId()); // 先停止现有任务
ScheduledFuture<?> scheduledFuture = null;
if (task.getType() == 0) {
int seconds = task.getSeconds();
if(seconds <= 0) {
seconds = 30;
}
//ThreadPoolTaskScheduler
scheduledFuture = taskScheduler.scheduleAtFixedRate(
() -> executeTask(task),
Duration.ofSeconds(seconds)
);
} else {
String cron = task.getCron();
scheduledFuture = taskScheduler.schedule(
() -> executeTask(task),
new CronTrigger(cron)
);
}
log.info("要启动的任务: {}", task.getId());
futureMap.put(task.getId(), scheduledFuture);
}
// 停止任务
public void stopTask(String areaId) {
log.info("要停止的任务id: {}", areaId);
if (futureMap.containsKey(areaId)) {
log.info("任务存在,即将停止: {}", areaId);
futureMap.get(areaId).cancel(true);
futureMap.remove(areaId);
}
}
private void executeTask(DemoTask task) {
log.info("execute task: {}, taskType: {}, methodName: {}", task.getId(), task.getType(), task.getMethodName());
try {
String[] split = task.getMethodName().split("#");
String className = split[0];
String methodName = split[1];
Class<?> aClass = Class.forName(className);
Object bean = applicationContext.getBean(aClass);
MethodInvoker invoker = new MethodInvoker();
invoker.setTargetObject(bean);
invoker.setTargetMethod(methodName);
invoker.setArguments(task.getInput());
invoker.prepare();
invoker.invoke();
} catch (Exception e) {
log.error("executeTask出现错误", e);
}
}
}
测试
接口:
Java
@RestController
public class TestController {
@Autowired
private DemoTaskService demoTaskService;
@PostMapping("startTask")
public String startTask(@RequestBody DemoTask task) {
demoTaskService.startTask(task);
return "ok start " + task.getId();
}
@GetMapping
public String stopTask(@PathVariable String taskId) {
demoTaskService.stopTask(taskId);
return "ok stop " + taskId;
}
}
任务:
Java
@Slf4j
@Component
public class DemoTestTask {
public void test1(String input) {
log.info("start test1 input: {}", input);
}
public void test2(String input) {
log.info("start test2 input: {}", input);
}
}
参数:
{
"id": 111111,
"type": 0,
"seconds": 10,
"cron": "*/20 * * * * ?",
"input": "hahaha",
"methodName": "com.example.demo.runner.DemoTestTask#test1"
}
{
"id": 222222,
"type": 1,
"seconds": 10,
"cron": "*/20 * * * * ?",
"input": "hehehe",
"methodName": "com.example.demo.runner.DemoTestTask#test2"
}
效果:
2026-05-16T15:49:27.518+08:00 INFO 15640 --- [demo] [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2026-05-16T15:49:27.518+08:00 INFO 15640 --- [demo] [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2026-05-16T15:49:27.518+08:00 INFO 15640 --- [demo] [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms
2026-05-16T15:49:27.658+08:00 INFO 15640 --- [demo] [nio-8080-exec-1] c.example.demo.service.DemoTaskService : 要停止的任务id: 111111
2026-05-16T15:49:27.658+08:00 INFO 15640 --- [demo] [nio-8080-exec-1] c.example.demo.service.DemoTaskService : 要启动的任务: 111111
2026-05-16T15:49:27.658+08:00 INFO 15640 --- [demo] [ scheduling-1] c.example.demo.service.DemoTaskService : execute task: 111111, taskType: 0, methodName: com.example.demo.runner.DemoTestTask#test1
2026-05-16T15:49:27.658+08:00 INFO 15640 --- [demo] [ scheduling-1] com.example.demo.runner.DemoTestTask : start test1 input: hahaha
2026-05-16T15:49:37.666+08:00 INFO 15640 --- [demo] [ scheduling-1] c.example.demo.service.DemoTaskService : execute task: 111111, taskType: 0, methodName: com.example.demo.runner.DemoTestTask#test1
2026-05-16T15:49:37.666+08:00 INFO 15640 --- [demo] [ scheduling-1] com.example.demo.runner.DemoTestTask : start test1 input: hahaha
2026-05-16T15:49:44.446+08:00 INFO 15640 --- [demo] [nio-8080-exec-3] c.example.demo.service.DemoTaskService : 要停止的任务id: 222222
2026-05-16T15:49:44.461+08:00 INFO 15640 --- [demo] [nio-8080-exec-3] c.example.demo.service.DemoTaskService : 要启动的任务: 222222
2026-05-16T15:49:47.667+08:00 INFO 15640 --- [demo] [ scheduling-1] c.example.demo.service.DemoTaskService : execute task: 111111, taskType: 0, methodName: com.example.demo.runner.DemoTestTask#test1
2026-05-16T15:49:47.667+08:00 INFO 15640 --- [demo] [ scheduling-1] com.example.demo.runner.DemoTestTask : start test1 input: hahaha
2026-05-16T15:49:57.666+08:00 INFO 15640 --- [demo] [ scheduling-1] c.example.demo.service.DemoTaskService : execute task: 111111, taskType: 0, methodName: com.example.demo.runner.DemoTestTask#test1
2026-05-16T15:49:57.666+08:00 INFO 15640 --- [demo] [ scheduling-1] com.example.demo.runner.DemoTestTask : start test1 input: hahaha
2026-05-16T15:50:00.011+08:00 INFO 15640 --- [demo] [ scheduling-1] c.example.demo.service.DemoTaskService : execute task: 222222, taskType: 1, methodName: com.example.demo.runner.DemoTestTask#test2
2026-05-16T15:50:00.011+08:00 INFO 15640 --- [demo] [ scheduling-1] com.example.demo.runner.DemoTestTask : start test2 input: hehehe
2026-05-16T15:50:07.676+08:00 INFO 15640 --- [demo] [ scheduling-1] c.example.demo.service.DemoTaskService : execute task: 111111, taskType: 0, methodName: com.example.demo.runner.DemoTestTask#test1
2026-05-16T15:50:07.676+08:00 INFO 15640 --- [demo] [ scheduling-1] com.example.demo.runner.DemoTestTask : start test1 input: hahaha
2026-05-16T15:50:17.665+08:00 INFO 15640 --- [demo] [ scheduling-1] c.example.demo.service.DemoTaskService : execute task: 111111, taskType: 0, methodName: com.example.demo.runner.DemoTestTask#test1
2026-05-16T15:50:17.665+08:00 INFO 15640 --- [demo] [ scheduling-1] com.example.demo.runner.DemoTestTask : start test1 input: hahaha
2026-05-16T15:50:20.009+08:00 INFO 15640 --- [demo] [ scheduling-1] c.example.demo.service.DemoTaskService : execute task: 222222, taskType: 1, methodName: com.example.demo.runner.DemoTestTask#test2
2026-05-16T15:50:20.009+08:00 INFO 15640 --- [demo] [ scheduling-1] com.example.demo.runner.DemoTestTask : start test2 input: hehehe
2026-05-16T15:50:27.668+08:00 INFO 15640 --- [demo] [ scheduling-1] c.example.demo.service.DemoTaskService : execute task: 111111, taskType: 0, methodName: com.example.demo.runner.DemoTestTask#test1
2026-05-16T15:50:27.668+08:00 INFO 15640 --- [demo] [ scheduling-1] com.example.demo.runner.DemoTestTask : start test1 input: hahaha
2026-05-16T15:50:37.669+08:00 INFO 15640 --- [demo] [ scheduling-1] c.example.demo.service.DemoTaskService : execute task: 111111, taskType: 0, methodName: com.example.demo.runner.DemoTestTask#test1
2026-05-16T15:50:37.669+08:00 INFO 15640 --- [demo] [ scheduling-1] com.example.demo.runner.DemoTestTask : start test1 input: hahaha
2026-05-16T15:50:40.012+08:00 INFO 15640 --- [demo] [ scheduling-1] c.example.demo.service.DemoTaskService : execute task: 222222, taskType: 1, methodName: com.example.demo.runner.DemoTestTask#test2
2026-05-16T15:50:40.012+08:00 INFO 15640 --- [demo] [ scheduling-1] com.example.demo.runner.DemoTestTask : start test2 input: hehehe
上面的日志可以看到,111111和222222这两个定时任务,调接口启动后,这两个任务确实按10秒和20秒的定时在跑了