定时器 Cron表达式

                                                   Cron表达式

 

一、前言

       在开发中,我们往往需要用到定时任务(quartz)来实现业务需求;

           往往头疼的不是逻辑,而是最后的,如何定义Cron表达式(不难,but容易忘 ^_^)。

           总结如下:

二、Cron表达式定义

       ①、列 举几个cron表达式示例:       

           0   0   0   *   *   ?             含义:每天0:00执行一次定时任务

           0   0   0   ?   *   MON      含义:每周周一0:00执行一次定时任务

           0   0   0   1   *   ?             含义:每月1号0:00执行一次定时任务

      ②、这 样就可以确定格式:

                【 秒 分 时 日 月 周 年 】,其中年是可选类型,也就是说他如果在不设定年分的情况下是每年。

                             ↓↓↓↓↓↓↓↓

      ③、格 式定义      

字段

允许值

允许的特殊字符

Seconds (秒)

0-59

, - * /

Minutes(分)

0-59

, - * /

Hours(时)

0-23

, - * /

Day-of-Month(天)

1-31

, - * ? / L W C

Month(月)

1-12 或者 JAN-DEC (a)

, - * /

Day-of-Week(周)

1-7 或者 SUN-SAT (b)

, - * ? / L C #

年(可选字段)

留空, 1970-2099

, - * /

 

                (a). JAN,FEB,MAR,APR,MAY,JUNE,JULY,AUG,SEP,OCT,NOW,DEC

                (b). SUN,MON,TUE,WED,THU,FRI,SAT

     ③、特 殊字符定义

               “*”字符: 通配符,指定所有的值;

                               eg: 0 * * * * ?  表示每分钟执行一次

                               eg: 0 * * ? * *  表示每分钟的00秒执行一次

 

               “?”字符: 只在日期域和星期域中使用,指定"非明确的值";

                               eg: 0 10 18 15 3 ?      表示每年三月的第15天,下午6点10分都执行一次

                               eg: 0 10 18 ? 3 WEB  表示每年3月的每个星期三,下午6点10分都执行一次

 

               “,”字符:  表示列出枚举值;

                               eg: 10,20  *  * ? * *    表示每分钟的第10秒与第20秒都执行一次

                               eg: 0 10,20 * 1,2 * ?  表示每月的第1天与第2天的,每小时的第

                                                                 10分钟与第20分钟都执行一次

 

               “-”字符:  指定一个范围;

                               eg: 0 10 18 1-5 * ?  表示每月的1号到5号(包含1/5号,每月共计5天),

                                                              下午6点10分都执行一次

                               eg: 0 10-15 * ? * *  表示每小时的第10分钟到第15分钟(包含10/15分钟,

                                                               每小时共计5分钟)都执行一次

 

               “/”字符:  指定一个值的增加幅度。n/m表示从n开始,每次增加m;

                               eg: 5/20 * * ? * *  表示每分钟的第5秒,第25秒,第45秒都执行一次

                               eg: 0 * 2/2 ? *  *  表示每天的第2/4/6/8.../22小时的0分0秒都执行一次

 

               “L”字符:  只在日期域和星期域中使用,用在日表示一个月中的最后一天,

                                用在周表示该月最后一个星期X;

 

               “W”字符:只在日期域出现,指定离给定日期最近的工作日(周一到周五),

                                “L”和“W”可以在日期域中联合使用,LW表示这个月最后一周的工作日;

 

               “#”字符:  只在星期域中出现,表示该月第几个周X。6#3表示该月第3个周五;

                               eg: * * * ? * 3#4  表示每月的第4个星期的周2,凌晨都执行一次

                               eg: * * * ? * 6#2  表示每月的第2个星期的周5,凌晨都执行一次

 

               “C”字符: 只在日期域和星期域出现,这个字符依靠一个指定的“日历”。

 

三、常用Cron表达式示例

 

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

四、友情链接

       在 线自动生成Cron表达式网址:

           http://cron.qqe2.com/

### Spring Boot 动态 Cron 表达式实现定时任务 在 Spring Boot 中,动态更新 Cron 表达式的功能可以通过多种方法实现。以下是基于 Quartz 和 `@Scheduled` 注解两种常见的方式。 #### 方法一:使用 Quartz 实现动态 Cron 定时任务 Quartz 提供了一个强大的任务调度机制,支持运行时修改 Cron 表达式。要实现这一目标,需完成以下操作: 1. **引入 Quartz 依赖** 在项目的 `pom.xml` 文件中添加 Quartz 的 Maven 依赖[^1]。 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> ``` 2. **创建 Job 类** 创建一个继承自 `Job` 接口的类,并重写其 `execute` 方法定义具体逻辑。 ```java import org.quartz.Job; import org.quartz.JobExecutionContext; public class MyDynamicJob implements Job { @Override public void execute(JobExecutionContext context) { System.out.println("动态定时任务正在执行..."); } } ``` 3. **配置 Scheduler 工厂并动态设置 Cron 表达式** 使用 `Scheduler` 对象手动触发任务调度,并允许通过 API 修改 Cron 表达式。 ```java import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.stereotype.Component; @Component public class DynamicCronConfigurer implements ApplicationListener<ContextRefreshedEvent> { @Autowired private Scheduler scheduler; @Override public void onApplicationEvent(ContextRefreshedEvent event) { try { updateJobWithNewCronExpression("0/5 * * * * ?"); } catch (Exception e) { throw new RuntimeException(e); } } public void updateJobWithNewCronExpression(String cronExpression) throws Exception { TriggerKey triggerKey = TriggerKey.triggerKey("myTrigger", "group1"); // 获取现有的触发器 CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); if (trigger == null) { createInitialJob(cronExpression); return; } String oldTime = trigger.getCronExpression(); if (!oldTime.equalsIgnoreCase(cronExpression)) { TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger() .withIdentity(triggerKey) .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)); scheduler.rescheduleJob(triggerKey, triggerBuilder.build()); System.out.println("已成功更新 Cron 表达式:" + cronExpression); } } private void createInitialJob(String cronExpression) throws Exception { JobDetail jobDetail = JobBuilder.newJob(MyDynamicJob.class).withIdentity("job1", "group1").build(); Trigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "group1") .startNow() .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)) .build(); scheduler.scheduleJob(jobDetail, trigger); System.out.println("初始任务已创建,Cron 表达式:" + cronExpression); } } ``` --- #### 方法二:使用 `@Scheduled` 注解配合动态刷新策略 如果不想引入额外的库,可以利用 Spring 自带的 `@Scheduled` 注解结合动态刷新机制来实现类似的动态 Cron 调度效果[^3]。 1. **启用定时任务** 在主程序入口处添加 `@EnableScheduling` 注解以开启定时任务支持[^2]。 ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 2. **编写可动态调整的定时任务** 利用外部化配置文件(如 application.properties 或数据库表),存储当前生效的 Cron 表达式,并周期性读取该值进行校验和更新。 ```java import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class DynamicCronTask { private final Logger logger = LoggerFactory.getLogger(DynamicCronTask.class); @Value("${dynamic.cron.expression}") private String dynamicCronExpression; /** * 周期性检测 Cron 表达式变化 */ @Scheduled(fixedRate = 5000L) public void refreshCron() { logger.info("当前 Cron 表达式为 {}", dynamicCronExpression); } /** * 执行实际业务逻辑的任务 */ @Scheduled(cron = "${dynamic.cron.expression}") // 绑定到属性中的 Cron 表达式 public void performTask() { logger.info("动态定时任务被触发!"); } } ``` 3. **动态更改 Cron 表达式** 可以通过 RESTful API 更新应用上下文中对应的属性值,或者重启服务加载最新的配置项。 --- ### 总结 上述两种方式分别适用于不同场景需求: - 如果需要更复杂的功能扩展以及更高的灵活性,则推荐采用 Quartz 方案; - 若仅满足简单的动态 Cron 更改诉求,内置的 `@Scheduled` 即足以胜任。 问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值