Java动态定时任务

基于上一篇动态多定时任务,想到貌似可以将其扩展一下,于是有了这篇。
上一篇链接

完整代码:

实体类:

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秒的定时在跑了

相关推荐
haiyangyiba1 小时前
修改jar包中class的包路径
java·jar·修改class·修改class中包路径
雨落在了我的手上2 小时前
初识java(七):Java调试案例讲解
java·intellij-idea·集成开发环境调试功能
Volunteer Technology2 小时前
Spring AI MCP 案例-WebFlux SSE传输模式 (九)
java·数据库·人工智能·spring
rabbit_pro2 小时前
SpringBoot3集成Langchain4j使用Ollama
java·开发语言
解决问题no解决代码问题2 小时前
JAVA GC
java·开发语言·jvm
小程故事多_803 小时前
Agent Loop 核心突破,上下文压缩四大流派,重新定义窗口资源利用率
java·开发语言·人工智能
神仙别闹3 小时前
基于Java+MySQL实现(GUI)医院管理系统
java·mysql·oracle
吴声子夜歌4 小时前
Java——显示条件
java·开发语言
AC赳赳老秦4 小时前
OpenClaw与WPS宏联动:批量执行WPS复杂操作,解决办公表格批量处理难题
java·前端·数据库·自动化·需求分析·deepseek·openclaw