Spring 定时任务 @Scheduled

1. 定时任务的使用

1.1 使用示例

  1. 在启动类上添加 @EnableScheduling注解

    @SpringBootApplication
    @EnableAsync
    @EnableScheduling
    public class Application {
       public static void main(String[] args) {
           SpringApplication.run(Application.class, args);
       }
    }
    
  2. 创建任务类,在需要定时执行的方法上面添加注解@Scheduled,并指定执行计划

    @Slf4j
    @Component
    @Lazy(false)
    public class CreateTableJob {
    
      @Autowired
      private ActionEventRepository actionEventRepository;
    
     /**
      * 每月 28 号 00:00:00 创建下月的表
      */
      @Scheduled(cron = "0 0 0 28 1-12 ?")
      public void createTable() {
        String tableName = ActionEventTableUtil.getNextMonthTableName();
        log.warn("It is time to create next month table:{}", tableName);
        try {
            actionEventRepository.createTable(tableName);
        } catch (Exception e) {
            log.warn("Cron job create next month table:" + tableName + "fail!", e);
        }
      }
    }
    

1.2 注意事项

1.定时执行的方法不能有参数
2.定时执行的方法不能有返回值
3.@Scheduled默认是单线程串行执行,多个定时任务同时执行可能会发生阻塞。此时可在启动类上添加注解@EnableAsync,并在定时执行的方法上添加注解 @Async使其异步执行
4. Spring 打开延时加载策略时会导致定时任务类没在启动时加载进任务队列,无法正确执行。解决方法是在定时任务类上添加注解@Lazy(false),指定其关闭延时加载策略

2. Cron 表达式相关

2.1 Cron 表达式格式

Cron 表达式的格式是 [Seconds] [Minutes] [Hours] [DayofMonth] [Month] [DayofWeek] [Year]

字段 候选值 允许的特殊字符
秒(Seconds) 0~59的整数 , - * /
分(Minutes) 0~59的整数 , - * /
小时(Hours) 0~23的整数 , - * /
日期(DayofMonth) 1~31的整数(但需考虑各月的天数) ,- * ? / L W C
月份(Month) 1~12的整数或 JAN-DEC , - * /
星期(DayofWeek) 1~7的整数或者 SUN-SAT (1=SUN) , - * ? / L C #
年(可选,留空)(Year) 1970~2099 , - * /

2.2 特殊字符详解

特殊符号 含义
* 代表所有的取值范围内的数字
/ 代表每的意思,"0/5"表示从0位置开始,每5个单位执行一次
- 代表范围,比如从某个数字到某个数字
, 分开的几个枚举值
? 只能用在 DayofMonth 和 DayofWeek 两个域,表示不指定值。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用写法:13 13 15 20 * ?, 其中最后一位只能用,而不能使用*,如果使用*表示不管星期几都会触发,这会产生冲突
L 表示最后,只能出现在 DayofWeek 和 DayofMonth 域。如果在 DayofWeek 域使用5L, 意味着在最后的一个星期四触发
W 表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份
LW 这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。
# 用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三

2.3 常见例子

Cron在线工具

0 15 10 ? 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作业
0 0 10,14,16 * * ?   每天上午10点,下午2点,40 0/30 9-17 * * ?   朝九晚五工作时间内每半小时 
0 15 10 ? * 6#3   每月的第三个星期五上午10:15触发
发布了97 篇原创文章 · 获赞 88 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_45505313/article/details/104522215