You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现支持运行时调整的每日指定时间点方法执行方案

动态每日定时任务实现方案

你要的这种运行时可修改、支持多时间点的每日定时执行能力,不用找第三方组件,Spring生态自带的ThreadPoolTaskScheduler就可以完全满足,属于开箱即用,不需要额外引入依赖。

核心实现逻辑

  • 利用ThreadPoolTaskScheduler提供的动态任务注册能力,支持运行时新增、移除定时任务,比固定写死@Scheduled(cron = "xxx")的原生方案灵活度高很多
  • 每次收到新的时间点配置消息时,先把之前注册的所有旧任务全部注销,再按照新的时间点批量注册新任务,保证触发规则和最新配置完全一致
  • 你收到的HH:mm格式时间点,直接拼接转成标准Cron表达式即可,单个时间点对应一个Cron触发器,多时间点就注册多个触发器,没有数量限制

极简实现代码

import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledFuture;

@Component
public class DynamicDailyTask {

    @Resource
    private ThreadPoolTaskScheduler taskScheduler;

    // 持有所有已注册任务的句柄,更新配置时用来注销旧任务
    private final List<ScheduledFuture<?>> taskHandles = new ArrayList<>();

    @PostConstruct
    private void initScheduler() {
        // 线程池大小根据自身任务并发量调整即可
        taskScheduler.setPoolSize(3);
        taskScheduler.initialize();
    }

    /**
     * 配置消息接收入口,收到新的时间点列表直接调用该方法刷新规则
     * @param hhMmTimePoints 格式示例:["00:12", "12:20", "15:40"]
     */
    public void updateTriggerRules(List<String> hhMmTimePoints) {
        // 先清除所有旧任务,避免旧配置的任务继续触发
        taskHandles.forEach(handle -> handle.cancel(false));
        taskHandles.clear();

        // 按新时间点逐个注册任务
        for (String timePoint : hhMmTimePoints) {
            String[] timePart = timePoint.split(":");
            // 拼接为每日定点执行的Cron表达式:秒 分 时 日 月 周
            String cronExpr = String.format("0 %s %s * * ?", timePart[1], timePart[0]);
            ScheduledFuture<?> handle = taskScheduler.schedule(
                    this::runYourBizLogic,
                    new CronTrigger(cronExpr)
            );
            taskHandles.add(handle);
        }
    }

    /**
     * 你需要定时执行的业务方法
     */
    private void runYourBizLogic() {
        // 写自己的业务逻辑即可
    }
}

注意事项

  • 注销任务时cancel方法传false,不要强制中断正在运行的业务任务,等当前执行中的任务自然结束即可
  • 时间点参数记得加格式校验,避免非法的时间值传入导致Cron表达式生成失败,最好加配置异常告警
  • 如果是多实例部署,要加分布式锁保证同一时间点只有一个实例执行业务,或者把调度节点单独部署为单实例,避免任务重复执行

如果你的项目本身已经引入了Quartz调度框架,也可以用Quartz的动态作业管理能力实现相同效果,但没必要为了这个需求单独引入Quartz,功能太重,上面的原生方案足够覆盖需求,稳定性也足够。

内容的提问来源于stack exchange,提问作者Evgeniy Zelenskiy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:48:53