SpringTask--介绍及其使用

SpringTask

介绍:

  • Spring Task 是Spring框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑。
  • Spring3.0以后自主开发的定时任务工具,可以看做是一个轻量级的Quartz框架。使用起来很简单,除spring相关的包外不需要额外的包
  • **定位:**定时任务框架
  • **作用:**定时自动执行某段Java代码

为什么需要SpringTask:

  • 信用卡每月还款提醒
  • 银行贷款每月还款提醒
  • 火车票售票系统处理未支付订单
  • 入职纪念日为用户发送通知
  • **强调:**只要是需要定时处理的场景都可以使用Spring Task

常见定时任务方案

  • 实现定时任务的方案多种多样,其中用的较多的如下:

  • jdk的Timer和TimerTask:

    • 可以实现简单的间隔执行任务,无法实现按日历去调度执行任务。
  • Quartz任务调度框架:

    • Quartz是一个异步任务调度框架,功能丰富,可以实现按日历调度,这种开发中用的比较多,但是稍微复杂一点,不过功能非常强大。
  • Spring Task:

    • Spring 3.0后提供Spring Task实现任务调度,支持按日历调度,相比Quartz功能稍简单,但是在开发基本够用,支持注解编程方式。如果Spring Task能够满足开发需求的话,尽量用Spring Task,毕竟是Spring全家桶中的一员,如果不能满足开发需求,这时候再考虑去使用Quartz框架。

cron表达式

  • 在线Cron表达式生成器:https://cron.qqe2.com/

  • cron表达式其实就是一个字符串,通过cron表达式可以定义任务触发的时间

  • **构成规则:**分为6或7个域,由空格分隔开,每个域代表一个含义

    每个域的含义分别为:秒、分钟、小时、日、月、周、年(可选)

  • 举例:

    2022年10月12日上午9点整 对应的cron表达式为:0 0 9 12 10 ? 2022

    image-20221218184412491

    说明:一般的值不同时设置,其中一个设置,另一个用?表示。

  • **比如:**描述2月份的最后一天,最后一天具体是几号呢?可能是28号,也有可能是29号,所以就不能写具体数字。

    为了描述这些信息,提供一些特殊的字符。这些具体的细节,我们就不用自己去手写,可以使用在线cron表达式生成器

    序号说明必填允许填写的值允许的通配符
    10-59, - * /
    20-59, - * /
    30-23, - * /
    41-31, - * ? / L W
    51-12 / JAN-DEC, - * /
    61-7 or SUN-SAT, - * ? / L #
    71970-2099, - * /
  • 通配符说明:

    • *表示所有值。 例如:在分的字段上设置 *,表示每一分钟都会触发。
    • ? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作,但不关心是周几,所以需要周位置的那个字段设置为”?” 具体设置为 0 0 0 10 * ?
    • - 表示区间。例如 在小时上设置 “10-12”,表示 10,11,12点都会触发。
    • , 表示指定多个值,例如在周字段上设置 “MON,WED,FRI” 表示周一,周三和周五触发
    • / 用于递增触发。如在秒上面设置”5/15” 表示从5秒开始,每增15秒触发(5,20,35,50)。 在月字段上设置’1/3’所示每月1号开始,每隔三天触发一次。
    • L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会依据是否是润年[leap]), 在周字段上表示星期六,相当于”7”或”SAT”。如果在”L”前加上数字,则表示该数据的最后一个。例如在周字段上设置”6L”这样的格式,则表示“本月最后一个星期五”
    • W 表示离指定日期的最近那个工作日(周一至周五). 例如在日字段上置”15W”,表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发, 如果15号是周未,则找最近的下周一(16号)触发.如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 “1W”,它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,”W”前只能设置具体的数字,不允许区间”-“)。
    • #序号(表示每月的第几个周几),例如在周字段上设置”6#3”表示在每月的第三个周六.注意如果指定”#5”,正好第五周没有周六,则不会触发该配置(用在母亲节和父亲节再合适不过了) ;小提示:’L’和 ‘W’可以一组合使用。如果在日字段上设置”LW”,则表示在本月的最后一个工作日触发;周字段的设置,若使用英文字母是不区分大小写的,即MON与mon相同。

基本使用:

  1. 首先,需要在启动类上加上注解@EnableScheduling
@EnableScheduling
public class ApiAutoConfiguration {}
  1. 当要创建一个定时任务时,@Scheduled可以直接注解在无返回值无参数方法上,表示该方法根据注解的规则定时执行。
    • @Scheduled注解主要支持三种方式:
    • 以下参数cron/fixedDelay/fixedRate三个属性必须且只能出现一个
    • cron方式:@Scheduled(cron = "0 0 2 * * ? ")
    • 固定速率:@Scheduled(initialDelay = 5000, fixedDelay = 2000),单位毫秒
    • 固定延时:@Scheduled(initialDelay = 5000, fixedRate = 2000),单位毫秒
@Scheduled(cron = "0 0 2 * * ? ")
public void timerClean() {
}

线程池参数

  • springboot对于spring-task默认是创建了一个线程数为1的线程池。
  • 可以通过配置文件对线程参数进行调整。
spring:
	task:
  	scheduling:
    	thread-name-prefix: scheduling-
    	pool:
      	size: 1
  • 如果想更深度定制线程池,也可以自己实现TaskScheduler接口,并注册为Bean:
@Bean
public TaskScheduler taskScheduler() {
    return new TaskSchedulerImpl();
}

调度效果

  • springboot内部是自动创建了一个ThreadPoolTaskScheduler对象,它实现了TaskScheduler接口,该类内部是使用了ScheduledExecutorService,因此任务调度的效果可参考ScheduledExecutorService文章。

  • 不过经过了spring的封装,还是有部分与ScheduledExecutorService有区别。

  • 区别1:@Scheduled注解方法执行时抛出异常,不会导致线程终止,不影响任务的下一次执行
    spring-task对于任务执行,进行了统一的try catch,并设置了ErrorHandler进行错误日志打印。

  • 区别2:Spring-Task扩展了对CRON的支持,其对任务耗时超过间隔时间的处理方式与固定延时相同

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值