Spring定时任务 @Scheduled注解

定时任务@Scheduled注解

1.配置文件

使用spring @Scheduled注解执行定时任务添加配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd"
    default-autowire="byName" default-lazy-init="false">

    <!-- 定时任务相关配置 -->
    <task:executor id="executor" pool-size="10" queue-capacity="128"/>
    <task:scheduler id="scheduler" pool-size="10"/>
    <task:annotation-driven executor="executor" scheduler="scheduler" proxy-target-class="true"/>
</beans>

spring boot等框架集成了schedule,添加maven依赖包即可

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

启动类,添加启动注解
在springboot入口或者配置类中增加@EnableScheduling注解即可启用定时任务。

@EnableScheduling
@SpringBootApplication
public class ScheduleApplication {
    public static void main(String[] args) {
        SpringApplication.run(ScheduleApplication.class, args);
    }
}

2.调用

在Java代码中使用
EztVoV.png

@Component
public class testScheduled {

    @Scheduled(cron = "0/5 * * * * ?")//每5秒执行一次
    public void run() {

  }
}

3.关于cron参数

cron参数生成器

一个cron表达式有至少6个或7个(一般是6个)有空格分隔的时间元素。

按顺序依次为

  • 秒(0~59)
  • 分钟(0~59)
  • 小时(0~23)
  • 天(月)(0~31,但是你需要考虑你月的天数)
  • 月(0~11)
  • 天(星期)(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT)
  • 年份(1970-2099)——@Scheduled是不支持的,spring quartz支持
字段 允许值 允许的特殊字符
0-59 , - * /
0-59 , - * /
小时 0-23 , - * /
日期 1-31 , - * ? / L W C
月份 1-12 或者 JAN-DEC , - * /
星期 1-7 或者 SUN-SAT , - * ? / L C #
留空, 1970-2099 , - * /

解析:

如: 0 0/1 * ? 每分钟执行一次

  1. ” 字符被用来指定所有的值
    若”
    “在分钟的字段域里表示“每分钟”
  2. “?”字符只在日期域和星期域中使用。它被用来指定“非明确的值”。当你需要通过在这两个域中的一个来指定一些东西的时候,它是有用的。
    月份中的日期和星期中的日期这两个元素时互斥的一起应该通过设置一个问号来表明不想设置那个字段。
  3. “-”字符被用来指定一个范围。如:“10-12”在小时域意味着“10点、11点、12点”。
  4. “,”字符被用来指定另外的值。如:“MON,WED,FRI”在星期域里表示”星期一、星期三、星期五”。
  5. “/”字符用于指定增量。
    如:

     “0/15”在秒域意思是每分钟的0,15,30和45秒。
     “5/15”在分钟域表示每小时的5,20,35和50。
    
  6. 符号“ ”在“/”前面(如: /10)等价于0在“/”前面(如:0/10)。

     表达式的每个数值域都是一个有最大值和最小值的集合
     如: 秒域和分钟域的集合是0-59,日期域是1-31,月份域是1-12。
     字符“/”可以帮助你在每个字符域中取相应的数值。如:“7/6”在月份域的时候只
     有当7月的时候才会触发,并不是表示每个6月。
    
  7. L是‘last’的省略写法可以表示day-of-month和day-of-week域,但在两个字段中的意思不同,例如day-of- month域中表示一个月的最后一天。如果在day-of-week域表示‘7’或者‘SAT’,如果在day-of-week域中前面加上数字,它表示 一个月的最后几天,例如‘6L’就表示一个月的最后一个星期五。

  8. 字符“W”只允许日期域出现。这个字符用于指定日期的最近工作日。例如:如果你在日期域中写 “15W”,表示:这个月15号最近的工作日。所以,如果15号是周六,则任务会在14号触发。如果15好是周日,则任务会在周一也就是16号触发。如果 是在日期域填写“1W”即使1号是周六,那么任务也只会在下周一,也就是3号触发,“W”字符指定的最近工作日是不能够跨月份的。字符“W”只能配合一个 单独的数值使用,不能够是一个数字段,如:1-15W是错误的。
  9. “L”和“W”可以在日期域中联合使用,LW表示这个月最后一周的工作日。
  10. 字符“#”只允许在星期域中出现。这个字符用于指定本月的某某天。例如:“6#3”表示本月第三周的星期五(6表示星期五,3表示第三周)。“2#1”表示本月第一周的星期一。“4#5”表示第五周的星期三。
  11. 字符“C”允许在日期域和星期域出现。这个字符依靠一个指定的“日历”。也就是说这个表达式的值依赖于相关的“日历”的计算结果,如果没有“日历” 关联,则等价于所有包含的“日历”。如:日期域是“5C”表示关联“日历”中第一天,或者这个月开始的第一天的后5天。星期域是“1C”表示关联“日历” 中第一天,或者星期的第一天的后1天,也就是周日的后一天(周一)。

举例:

每隔5秒执行一次:”/5 * ?”

每隔1分钟执行一次:”0 /1 ?”

每天23点执行一次:”0 0 23 ?”

每小时执行一次: “0 0 0/1 ?”

每天执行一次: “0 0 0 1/1 * ?”

每天凌晨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”

4.局限性——@Scheduled的cron无法指定执行的年份

若执行以下代码

    @Scheduled(cron = "0 18 10 * * ? 2016-2016")
    public void testTaskWithDate() {
        logger.info("测试2016.定时任务");
    }

将会报下面的错误

Cron expression must consist of 6 fields (found 7 in "0 18 10 * * ? 2016-2016")

错误原因是:

/**
 * Parse the given pattern expression.
 */
private void parse(String expression) throws IllegalArgumentException {
    String[] fields = StringUtils.tokenizeToStringArray(expression, " ");
    if (fields.length != 6) {
        throw new IllegalArgumentException(String.format(""
                + "cron expression must consist of 6 fields (found %d in %s)", fields.length, expression));
    }
spring taks 不支持年位定时,但是制定到年份,会存在一个问题,就是在你在过了这个时间后
再启动项目的时候,他会一直报一个memory leak的错误,大概的意思是你的定时任务将永远
不会被执行,导致项目一直启动不了。

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 定时任务@Scheduled注解
    1. 1.1. 1.配置文件
    2. 1.2. 2.调用
    3. 1.3. 3.关于cron参数
      1. 1.3.1. 解析:
      2. 1.3.2. 举例:
    4. 1.4. 4.局限性——@Scheduled的cron无法指定执行的年份
本站总访问量: , 本页阅读量: