scheduled一分钟执行一次_@Scheduled cron表达式

本文详细介绍了Cron表达式的各种域及其特殊字符的含义,并提供了多个示例。同时,展示了如何使用@Scheduled注解配合cron表达式实现定时任务,并在服务启动时执行一次任务的方法。

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

一、Cron详解:

Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式:

1.Seconds Minutes Hours DayofMonth Month DayofWeek Year

2.Seconds Minutes Hours DayofMonth Month DayofWeek

每一个域可出现的字符如下:

Seconds: 可出现", - * /"四个字符,有效范围为0-59的整数

Minutes:可出现", - * /"四个字符,有效范围为0-59的整数

Hours:可出现", - * /"四个字符,有效范围为0-23的整数

DayofMonth :可出现", - * / ? L W C"八个字符,有效范围为0-31的整数

Month:可出现", - * /"四个字符,有效范围为1-12的整数或JAN-DEc

DayofWeek:可出现", - * / ? L C #"四个字符,有效范围为1-7的整数或SUN-SAT两个范围。1表示星期天,2表示星期一, 依次类推

Year:可出现", - * /"四个字符,有效范围为1970-2099年

每一个域都使用数字,但还可以出现如下特殊字符,它们的含义是:

(1)*:表示匹配该域的任意值,假如在Minutes域使用*, 即表示每分钟都会触发事件。

(2) ?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和 DayofWeek会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,实际上并不是这样。

(3) -:表示范围,例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次

(4) /:表示起始时间开始触发,然后每隔固定时间触发一次,例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次.

(5) ,:表示列出枚举值值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。

(6) L:表示最后,只能出现在DayofWeek和DayofMonth域,如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。

(7) W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一 到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份。

(8) LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。

(9) #:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。

举几个例子:

每隔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 * * ?"

表示在每月的1日的凌晨2点调度任务:"0 0 2 1 * ? *"

表示周一到周五每天上午10:15执行作业:"0 15 10 ? * MON-FRI"

表示2002-2006年的每个月的最后一个星期五上午10:15执行:"0 15 10 ? 6L 2002-2006"

注意:由于"月份中的日期"和"星期中的日期"这两个元素互斥的,必须要对其中一个设置?

二、启动服务时执行任务

通过@Scheduled cron可以执行定时任务,而想要在服务启动时就先执行一次代码

可以通过 implements InitializingBean 重写 afterPropertiesSet 方法来调用一遍定时任务的方法来达到启动服务时执行一遍工作的效果

public class FuncReportScheduled implementsInitializingBean{/*** 每月月初执行一次*/@Scheduled(cron="0 0 0 1 * ?")

@Transactionalpublic voidfuncReportInit(){

log.info("---------------- 定时任务 ----------------");

}

@Overridepublic void afterPropertiesSet() throwsException {this.funcReportInit();

}

}

<think>好的,用户问的是“1分钟一次cron表达式”。首先,我需要确定用户对cron表达式的了解程度。可能用户正在设置定时任务,比如Java中的Quartz或者Spring的@Scheduled,或者是Linux的crontab。不同系统对cron表达式的格式可能略有不同,但大部分情况下格式是类似的。 用户的问题看起来直接,但需要确保回答准确。Cron表达式的基本结构是六个或七个字段,分别代表秒、分、时、日、月、周、年(可选)。在常见的Linux crontab中是五个字段:分、时、日、月、周,没有秒。但如果是Quartz等框架,通常支持六个字段,包括秒。 所以首先需要明确用户使用的场景。比如,如果是Spring的@Scheduled,它使用的是六个字段,包括秒。而如果是Linux的crontab,则是五个字段。用户可能没有说明具体环境,所以需要覆盖这两种情况。 接下来,正确的表达式是怎样的。对于每1分钟执行一次,如果是标准的Linux cron,应该是每分钟执行一次,对应的表达式是“* * * * *”,每个星号代表每分钟、每小时、每天、每月、每周都匹配。但如果是包含秒的情况,比如Quartz,可能需要写成“0 * * * * ?”其中秒字段是0,每分钟的0秒执行,而分字段是*,每小时每分钟执行,这样每整分钟执行一次,但可能需要确认。或者如果用户需要严格每60秒执行一次,可能需要不同的写法,比如“*/1 * * * * ?”在秒字段,但这样其实每秒钟都会执行,所以可能不正确。 这里可能存在误区。需要明确,标准的cron表达式不支持秒级的间隔,除非在支持扩展的系统中,比如Quartz。在标准crontab中,最小单位是分钟,所以“* * * * *”表示每分钟执行一次,当分钟数改变时触发。而如果用户需要更细粒度的秒级,可能需要使用其他方式,比如在代码中处理,或者在支持秒的系统中配置。 但用户的问题明确是“1分钟一次”,所以可能只需要每分钟触发一次。这时候标准表达式就是“* * * * *”。但如果用户的环境是支持秒的,比如Quartz,可能需要写成“0 * * * * ?”,这样每分钟的第0秒执行,每小时每分钟执行一次,即每分钟一次。 另外,用户可能存在的疑问是,如果写成“*/1 * * * *”,这在分字段是每1分钟一次,但实际上和“* * * * *”效果一样,因为*表示每个值,而*/1在分字段中也是每个分钟,所以两者等价。因此,正确的写法应该是“* * * * *”在五个字段的情况下,或者“0 * * * * ?”在六个字段的情况下,其中秒是0,分钟是*,表示每分钟的0秒触发。 还需要注意不同系统的差异,比如在Spring中,@Scheduled(cron = "0 * * * * *") 表示每分钟的第0秒执行,即每分钟一次。而Quartz可能需要类似的表达式。 总结:用户需要的是每分钟执行一次cron表达式,根据不同的系统环境,写法可能稍有不同。需要明确用户的具体使用场景,但通常给出两种常见情况的表达式,并解释清楚差异,以避免用户混淆。同时,提醒用户注意时区或系统配置可能带来的影响,确保任务按预期执行。</think>--- ### **Cron表达式格式说明** Cron表达式由6或7个字段组成,格式为: `秒 分 时 日 月 星期 [年]`(年可选)。 不同系统的实现可能略有差异,但核心逻辑一致。 --- ### **1分钟执行一次表达式** #### **标准格式(如Linux Crontab)** 若系统使用**5字段格式**(分、时、日、月、星期),表达式为: ```plaintext */1 * * * * ``` - `*/1`:每分钟触发一次 - `*`:其他字段匹配所有值 #### **扩展格式(如Spring/Quartz框架)** 若系统支持**6字段格式**(秒、分、时、日、月、星期),表达式为: ```plaintext 0 */1 * * * * ``` - `0`:秒字段固定为0(每分钟的第0秒触发) - `*/1`:分钟字段每1分钟触发一次 --- ### **验证示例** - **Linux Crontab** ```bash # 每分钟执行一次脚本 */1 * * * * /path/to/your/script.sh ``` - **Java Spring框架** ```java @Scheduled(cron = "0 */1 * * * *") public void runEveryMinute() { // 每分钟执行的任务 } ``` --- ### **常见误区** 1. **`* * * * *` 与 `*/1 * * * *` 的区别** - 两者效果相同,均表示每分钟触发。 - `*` 表示“匹配所有值”,而 `*/1` 表示“每1单位触发一次”。 2. **秒级触发需谨慎** - 若系统支持秒字段(如 `0/30 * * * * *`),可实现每30秒一次。 - 但**避免滥用高频任务**,可能引发性能问题。 --- ### **进阶场景** #### **固定分钟的第N秒触发** ```plaintext 30 */1 * * * * # 每分钟的第30秒触发(如 12:00:30, 12:01:30) ``` #### **避开整点高峰** ```plaintext 0 5-59/10 * * * * # 每小时的第5、15、25、35、45、55分钟触发 ``` --- ### **总结** | 场景 | 表达式 | 说明 | |---------------|------------------|-------------------------------| | 标准Crontab | `*/1 * * * *` | 每分钟触发,忽略秒级精度 | | Spring/Quartz | `0 */1 * * * *` | 每分钟的第0秒触发 | | 自定义秒触发 | `30 */1 * * * *` | 每分钟的第30秒触发 | 根据实际系统选择表达式,并通过工具(如 [Cron表达式在线验证器](https://crontab.guru/))测试逻辑是否符合预期。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值