You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring SchedulingConfigurer与CronTrigger每5分钟执行任务失效问题及正确Cron表达式生成

解决Spring SchedulingConfigurer每5分钟执行任务的问题

你遇到的问题核心是Cron表达式写错了,导致任务没有按每5分钟一次的频率执行。让我帮你梳理清楚:

问题分析

你当前使用的表达式是* */5 * * * *,这个表达式的含义是:每5分钟区间内的每一秒都执行一次任务(比如00:00:00到00:04:59的每一秒都会触发),这显然和你想要的"每5分钟执行一次"不符。

正确的Cron表达式

要实现每5分钟执行一次任务,正确的Spring Cron表达式应该是:

0 */5 * * * *

表达式字段解释(Spring Cron是6位,顺序为:秒 分 时 日 月 周):

  • 0:秒位,指定在分钟的第0秒执行(确保任务只在每个5分钟的整点时刻触发一次)
  • */5:分位,表示每5分钟(从0分开始,每隔5分钟触发)
  • * * * *:时、日、月、周位都为*,表示任意小时、任意日期、任意月份、任意星期都生效

修正后的代码实现

另外,建议把CronTrigger的实例化移到nextExecutionTime方法外面,避免每次调用都创建新对象,优化后的代码如下:

import java.util.Date;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;

@Configuration
@EnableScheduling
public class SchedulerConfig implements SchedulingConfigurer {
    @Bean(destroyMethod = "shutdown")
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(100);
    }

    // 提前初始化CronTrigger,避免重复创建
    private final CronTrigger fiveMinuteTrigger = new CronTrigger("0 */5 * * * *");

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
        taskRegistrar.addTriggerTask(() -> {
            System.out.println("Scheduler task is running: " + java.time.LocalDateTime.now());
        }, triggerContext -> fiveMinuteTrigger.nextExecutionTime(triggerContext));
    }
}

补充:Spring Cron表达式规则回顾

为了避免后续踩坑,再明确下Spring Cron的6个字段顺序和常用规则:

  • 字段顺序:秒(0-59)分(0-59)时(0-23)日(1-31)月(1-12/JAN-DEC)周(1-7/SUN-SAT,1代表周日)
  • 常用通配符:
    • *:匹配该字段的所有值
    • */n:表示每隔n个单位触发
    • ,:枚举多个取值
    • -:指定取值范围

内容的提问来源于stack exchange,提问作者Shailesh Vikram Singh

火山引擎 最新活动