spring task 是spring boot 3.0以上自带的task,

在Spring应用中,直接使用@Scheduled注解即可,但对于集群项目比较麻烦,需要避免集群环境下任务被多次调用的情况,而且不能动态维护,任务启动以后不能修改、暂停等。

一、Application

增加@EnableScheduling注解

 

二、定时执行

package com.example.demo;

import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
@EnableScheduling
public class taskTest {
    //使用cron属性可按照指定时间执行,本例指的是每1分钟执行一次;
    @Scheduled(cron = "0 0/1 * * * ?")
    public void test1() {
        System.out.println("[" + Thread.currentThread().getName() + "]" + "-----------test1-----------");
    }

    //使用cron属性可按照指定时间执行,本例指的是每1分钟执行一次;
    @Scheduled(cron = "0 0/1 * * * ?")
    public void test2() {
        System.out.println("[" + Thread.currentThread().getName() + "]" + "-----------test2-----------");
    }

}

三、cron表达式

注:下面内容主要参考Quartz的文档,对于Spring Task基本都适用。

cron表达式是由7个域组成的字符串,它们描述了任务计划的各个细节,这些域用空格分隔,每个域代表的含义如下:

  1. Seconds(秒)
  2. Minutes(分)
  3. Hours(时)
  4. Day-of-Month(日)
  5. Month(月)
  6. Day-of-Week(星期)
  7. Year(可选字段)(年)

示例:0 0 10 ? * WED表示每个星期三的10:00:00

表达式

{秒}

{分}

{时}

{日}

{月}

{周}

{年}(可选)

允许值

0~59

0~59

0~23

1~31

1~12

JAN~DEC

1~7

SUN~SAT

1970~2099

特殊值

, - * /

, - * /

, - * /

, - * /? L W C

, - * /

, - * /? L C #

, - * /

说明:下面描述中,XX域则表示cron表达式相应的位置,如域表示cron中第1个值,域则表示cron表达式第4个值等等。

  • 月份简称:JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC
  • 星期简称:SUNMONTUEWEDTHUFRISAT。其中,1表示SUN
  • ,:用来分割在域上指定的多个值。如:MON,WED,FRI在星期域里表示星期一、星期三、星期五
  • /:用于指定增量值。如分钟上使用0/15,表示从零开始,每隔15分钟,等价于0,15,30,45。如分钟上使用3/15,表示从第3分钟开始,每隔15分钟,等价于3,18,33,48x/y中x表示开始值,y表示步长。
  • *:表示匹配该域的任意值。如秒上使用*表示每秒触发一次。
  • -:表示指定一个范围,如分钟域上10-13,表示10分、11分、12分、13分
  • ?:表示不关心的域,可用于两个域上,主要用来解决两个域的冲突。和*类似,区别在于*关心域,只是域的值可以任意,?则表示对该域不关心,不需要看该域的内容,直接忽略。
  • L:表示最后,是单词last的首字母,可用于两个域上,用在上含义不同:
  • 域上表示月份中日期的最后一天,如一月的第31天、非闰年二月的第28天。
  • 域上单独使用仅表示7SAT,即仅表示周六。但是如果跟在其他值后,如6LFRIL则表示该月中最后一个星期五。
  • L还可以指定偏移量,如域指定L-3,表示该月倒数第3天。当使用L时其值尽量不要指定列表或范围,以免令人困惑。
  • W:用于域,表示距离指定日最近的星期几(周一至周五中的一个),如:域上值为15W则表示距离本月第15日最近的工作日。
  • #:用于域,表示该月的第n个星期几。如:域值为6#3FRI#3表示该月的第3个星期五。

四、@Scheduled(cron = "0 0 1 * * *")常用表达式示例

  • 0 0 10,14,16 * * ?每天上午10点、下午两点、下午4点整触发
  • 0 0/30 9-17 * * ? 每天朝九晚五内每隔半小时触发
  • 0 15 10 ? * MON-FRI 周一至周五的上午10:15触发
  • 0 0/5 * * * ?每5分钟触发
  • 10 0/5 * * * ?每隔5分钟的第10秒触发(即10:00:10、10:05:10、10:10:10等)
  • 30 * * * * ? 每半分钟触发
  • 30 10 * * * ? 每小时的10分30秒触发
  • 30 10 1 * * ? 每天1点10分30秒触发
  • 30 10 1 20 * ? 每月20号1点10分30秒触发
  • 30 10 1 20 10 ? * 每年10月20号1点10分30秒触发
  • 30 10 1 20 10 ? 2011 2011年10月20号1点10分30秒触发
  • 30 10 1 ? 10 * 2011 2011年10月每天1点10分30秒触发
  • 30 10 1 ? 10 SUN 2011 2011年10月每周日1点10分30秒触发
  • 15,30,45 * * * * ? 每15秒,30秒,45秒时触发
  • 15-45 * * * * ? 15到45秒内,每秒都触发
  • 15/5 * * * * ? 每分钟的每15秒开始触发,每隔5秒触发一次
  • 15-30/5 * * * * ? 每分钟的15秒到30秒之间开始触发,每隔5秒触发一次
  • 0 0/3 * * * ? 每小时的第0分0秒开始,每三分钟触发一次
  • 0 15 10 ? * MON-FRI 星期一到星期五的10点15分0秒触发
  • 0 15 10 L * ? 每个月最后一天的10点15分0秒触发
  • 0 15 10 LW * ? 每个月最后一个工作日的10点15分0秒触发
  • 0 15 10 ? * 5L 每个月最后一个星期四的10点15分0秒触发
  • 0 15 10 ? * 5#3 每个月第三周的星期四的10点15分0秒触发

五、Spring Boot 的 application.properties 中相关的配置说明

# 是否允许核心线程超时。这样可以动态增加和缩小线程池
spring.task.execution.pool.allow-core-thread-timeout=true
#  核心线程池大小 默认 8
spring.task.execution.pool.core-size=8
# 线程空闲等待时间 默认 60s
spring.task.execution.pool.keep-alive=60s
# 线程池最大数  根据任务定制
spring.task.execution.pool.max-size=10
#  线程池 队列容量大小
spring.task.execution.pool.queue-capacity=50
# 线程池关闭时等待所有任务完成
spring.task.execution.shutdown.await-termination=true
# 执行线程关闭前最大等待时间,确保最后一定关闭
spring.task.execution.shutdown.await-termination-period=50
# 线程名称前缀
spring.task.execution.thread-name-prefix=task-