回顾定时任务注解@Scheduled

本文深入解析Spring框架中的@Scheduled注解,讲解其在定时任务中的应用,包括fixedDelay和fixedRate的区别,以及如何利用cron表达式实现灵活的调度规则,提供常用Cron表达式实例和在线生成器链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 概述

@Scheduled注解是包org.springframework.scheduling.annotation中的一个注解,主要是用来开启定时任务。

二 @Scheduled注解的源码

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
    String CRON_DISABLED = "-";

    String cron() default "";

    String zone() default "";

    long fixedDelay() default -1L;

    String fixedDelayString() default "";

    long fixedRate() default -1L;

    String fixedRateString() default "";

    long initialDelay() default -1L;

    String initialDelayString() default "";
}

根据注解源码可知,该注解是方法声明式注解和注解类型声明式注解。

三 @Scheduled注解中的主要参数

fixedDelay

@Scheduled(fixedDelay = 5000)
//将一个方法以上一个调用任务的完成之间为基准,在上一个任务完成之后,5s后再执行该方法。
public void doSomething() { 
// something that should execute periodically
}

fixedRate

@Scheduled(fixedRate = 5000)
//将一个方法以固定速率5s调用一次执行,这个周期是一个任务开始时间为基准,从上一个任务开始执行后5秒后再调用一次。
public void doSomething() { 
// something that should execute periodically
}

上述两个重要的参数只是提了简单的定时调用规则,当需要更为复杂的调用时我们可以通过参数cron进行设置。

四 复杂调度之参数cron

我们可以通过参数corn来编写表达式,然后通过表达式来配置任务的执行时间。其中每个corn表达式中至少会存在6个用空格分隔的时间元素,它们顺序依次为:

  • 秒(0~59)
  • 分钟(0~59)
  • 小时(0~23)
  • 天(0~31)
  • 月(0~11)
  • 星期(1~7或者SUN-SAT[SUN,MON,TUE,WED,THU,FRI,SAT])
  • 年份(1970~2099)

Seconds Minutes Hours DayofMonth Month DayofWeek

Cron格式中每个时间元素的说明

时间元素可出现的字符有效数值范围
Seconds,- * /0~59
Minutes,- * /0~59
Hours,- * /0~23
DayofMonth,- * / ? L W0~31
Month,- * /1~12
DayofWeek,- * / ? L #1~7或者SUN~SAT

Cron格式中特殊字符说明

字符作用举例
列出枚举值在Minutes域中使用6,8,则表示6分钟和8分钟各触发一次
-表示触发的范围值在Minutes域中使用6-8,则表示从6分钟到8分钟之间每分钟触发一次
*匹配任意值在Minutes域中使用*,则表示每分钟都会触发一次
/起始时间开始触发,每隔固定时间触发一次在Minutes域中使用6/8,表示5分钟触发一次,每10分钟再触发一次
在DayofMonth和DayofWeek中,用于匹配任意值在DayofMonth域使用?,表示每天都触发一次
#在DayofMonth中,确定第几个星期几7#3表示第三个星期六
L表示最后在DayofWeek中使用6L,表示在最后一个星期五触发
W表示有效工作日(周一到周五)在DayofMonth使用5W,如果5日是星期六,则将最近的工作日4日触发一次

注意:LW是可以连用,表示在某个月最后一个工作日,#是用来确定每个月第几个星期几的,只能出现在DayofMonth域中。

常用的Cron表达式

每隔5秒执行一次:"*/5 * * * * ?"
每隔1分钟执行一次:"0 */1 * * * ?"
每天23点执行一次:"0 0 23 * * ?"
每天凌晨1点执行一次:"0 0 1 * * ?"
每月1号凌晨1点执行一次:"0 0 1 1 * ?"
每月最后一天23点执行一次:"0 0 23 L * ?"
每周星期天凌晨1点实行一次:"0 0 1 ? * L"
在26分、29分、33分执行一次:"0 26,29,33 * * * ?"
每天的0点、13点、18点、21点都执行一次:"0 0 0,13,18,21 * * ?"
每天上午10点,下午2点,4点:"0 0 10,14,16 * * ?"
朝九晚五工作时间内每半小时:"0 0/30 9-17 * * ?"
表示每个星期三中午12点:"0 0 12 ? * WED" 
每天中午12点触发:"0 0 12 * * ?"
每天上午10:15触发:"0 15 10 ? * *"
每天上午10:15触发:"0 15 10 * * ?"
每天上午10:15触发:"0 15 10 * * ? *"
2005年的每天上午10:15触发: "0 15 10 * * ? 2005"
在每天下午2点到下午2:59期间的每1分钟触发: "0 * 14 * * ?"
在每天下午2点到下午2:55期间的每5分钟触发: "0 0/5 14 * * ?"
在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发: "0 0/5 14,18 * * ?"
在每天下午2点到下午2:05期间的每1分钟触发: "0 0-5 14 * * ?" 
每年三月的星期三的下午2:10和2:44触发: "0 10,44 14 ? 3 WED" 
周一至周五的上午10:15触发: "0 15 10 ? * MON-FRI"
每月15日上午10:15触发: "0 15 10 15 * ?" 
每月最后一日的上午10:15触发: "0 15 10 L * ?"
每月的最后一个星期五上午10:15触发: "0 15 10 ? * 6L"
2002年至2005年的每月的最后一个星期五上午10:15触发: "0 15 10 ? * 6L 2002-2005"

在线Cron表达式生成器

<think>好的,我现在要解决用户关于Spring定时任务Cron表达式的问题。用户给出的表达式是'0 0 22 1 * ?',需要解释它的含义和在Spring中的用法。首先,我需要回顾Cron表达式的结构,确保自己理解正确。 Cron表达式通常有6或7个字段,分别代表秒、分、时、日、月、周、年(年可选)。在Spring中,使用的是6位格式,不括年。所以用户的表达式是6位,对应:秒、分、时、日、月、周。 接下来分解各个字段: - 第一位0:秒,表示在每分钟的0秒触发。 - 第二位0:分,表示在每小时的0分触发。 - 第三位22:时,表示在22点,也就是晚上10点。 - 第四位1:日,即每月的1号。 - 第五位*:月,表示每个月都触发。 - 第六位?:周,这里用?是因为日和周是互斥的,指定了日就不用指定周,所以这里用?表示忽略周。 组合起来,这个表达式就是在每个月的1号晚上10点整执行任务。而周中的问号是为了避免冲突,因为已经指定了具体的日期。 接下来需要确认Spring中Cron的格式是否支持这种写法。根据Spring文档,Cron表达式确实支持这些字段,并且允许使用?在日和周字段。同时,要注意Spring的Cron解析器可能和Quartz有所不同,需要确认是否有差异。例如,Quartz支持年字段,但Spring的@Scheduled注解使用的是6位,没有年,所以这里没问题。 然后要考虑用户可能的疑惑点,比如为什么用?在周字段,以及月和日的关系。需要解释清楚互斥规则,即如果指定了日,周就必须用?,反之亦然。这点在引用[1]中也提到了,除了日期和星期可以用?外,其他字段必须有具体值。 另外,应用场景方面,这个表达式适用于需要在每月固定日期执行的任务,比如生成月报表、数据归档等。用户可能需要了解如何在自己的Spring Boot应用中配置这个定时任务,所以需要给出代码示例,说明如何使用@Scheduled注解,并确保启用定时任务的功能,比如添加@EnableScheduling。 还要注意检查是否有常见的错误,比如字段顺序是否正确,数值范围是否合理。例如,小时是0-23,日期是1-31,月份是1-12或JAN-DEC,周是1-7或SUN-SAT。用户表达式中的数值都在合理范围内,所以没有问题。 最后,生成相关问题时要围绕Cron表达式在Spring中的使用、配置注意事项、调试方法以及与其他定时任务框架的对比,这样能帮助用户深入理解并解决潜在的问题。</think>### Spring定时任务Cron表达式解析 **表达式含义** Cron表达式`0 0 22 1 * ?`表示任务在**每月1日的22:00:00(晚上10点整)执行**。各字段含义如下: $$ \begin{aligned} &\text{秒} &0 &\quad \text{(每分钟的第0秒)} \\ &\text{分} &0 &\quad \text{(每小时的第0分)} \\ &\text{小时} &22 &\quad \text{(22点,即晚上10点)} \\ &\text{日} &1 &\quad \text{(每月1日)} \\ &\text{月} &* &\quad \text{(每个月)} \\ &\text{周} &? &\quad \text{(忽略周,与日期字段互斥)} \end{aligned} $$ 在Spring中,`?`仅允许用于**日期**或**星期**字段,表示“无意义值”,避免同时指定日期和星期导致的冲突[^1]。 --- ### 在Spring中的用法 1. **配置定时任务** 使用`@Scheduled`注解绑定Cron表达式: ```java @Component public class ScheduledTask { @Scheduled(cron = "0 0 22 1 * ?") public void monthlyReport() { // 每月1日22:00执行的逻辑,例如生成月报 } } ``` 2. **启用定时任务** 在Spring Boot启动类添加`@EnableScheduling`: ```java @SpringBootApplication @EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 3. **注意事项** - Cron表达式需符合Spring规范,字段顺序为`秒 分 小时 日 月 周`。 - 若表达式含空格,需用双引号裹(如`cron = "0 0 22 * * ?"`)。 - 调试时可通过日志验证任务触发时间,推荐使用在线工具(如[Cron Maker](https://www.cronmaker.com/))辅助验证。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值