Spring Task之定时任务

发布时间:2024年01月04日

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
Spring Task之定时任务


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

在软件开发中,定时任务是非常常见的需求。它们允许我们在预定的时间或间隔内自动执行某些特定的操作,如数据备份、文件清理、报表生成等。而 Spring Task 就是 Spring 框架提供的一个强大工具,用于简化定时任务的开发和管理。
通过 Spring Task,我们可以轻松地定义、配置和执行定时任务,无需关心复杂的线程管理和调度细节。它提供了灵活的任务执行机制,可以根据需求设置任务的执行时间、频率以及执行的逻辑。
在这篇博客中,我将深入探讨 Spring Task 之定时任务的相关概念和特性。我们将了解如何使用 Spring Task 来创建定时任务、配置任务执行的时间和频率,以及如何处理任务执行过程中的异常情况。
无论你是 Spring 框架的新手还是有经验的开发者,我相信这篇博客都将为你提供有价值的信息和实用的技巧。让我们一起探索 Spring Task 的世界,掌握定时任务的开发技能,为我们的项目增添自动化的魅力!
准备好开始了吗?让我们一起踏上这段定时任务的探索之旅吧!


提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是Spring Task

Spring Task是Spring框架提供的一种任务调度和异步处理的解决方案。它可以帮助开发者在Spring应用中轻松地实现定时任务、异步任务等功能,提高应用的效率和可维护性。
Spring Task的主要特点包括:简单易用、内置支持、灵活的任务调度、异步任务支持以及集成注解和监控管理。它提供了简洁的注解和配置方式,使得任务调度和异步处理变得容易上手。同时,Spring Task还支持基于cron表达式的定时任务调度,能够满足各种复杂的调度需求。

使用 Spring Task 的优势

  • 提供了简单而强大的注解和配置方式,简化了定时任务的创建和管理。
  • 集成了 Spring 的依赖注入功能,使得任务可以方便地获取其他服务和资源。
  • 支持任务的灵活调度,包括执行时间、重复间隔等。

Spring Task 的核心概念和组件

  • @EnableScheduling:启用定时任务支持的注解,通常配置在定时任务的配置类上。
  • @Scheduled:用于注解定时任务方法,指定任务的执行时间和重复规则。
  • TaskExecutor:任务执行器,负责执行定时任务的具体逻辑。

二、Spring Task_Cron表达式

Spring Task依靠Cron表达式配置定时规则。Cron表达式是一个字符串,分为6或7个域,每一个域代表一个含义,以空格隔开。有如下两种语法格式:

  • Seconds Minutes Hours DayofMonth Month DayofWeek Year
  • Seconds Minutes Hours DayofMonth Month DayofWeek

每一个域可出现的字符如下:
Seconds(秒):可以出现", - * /"四个字符,有效范围为0-59的整数。

  • *:表示匹配该域的任意值,在Seconds域使用*,表示每秒钟都会触发
  • ,:表示列出枚举值。在Seconds域使用5,20,表示在5秒和20秒各触发一次。
  • -:表示范围。在Seconds域使用5-20,表示从5秒到20秒每秒触发一次
  • /:表示起始时间开始触发,然后每隔固定时间触发一次。在Seconds域使用5/20, 表示5秒触发一次,25秒,45秒分别触发一次。

Minutes(分):域中可出现, - * /四个字符,以及0-59的整数
Hours(时):域中可出现, - * /四个字符,以及0-23的整数
DayofMonth(日期):域中可出现, - * / ? L W C八个字符,以及1-31的整数

  • C:表示和当前日期相关联。在DayofMonth域使用5C,表示在5日后的那一天触发,且每月的那天都会触发。比如当前是10号,那么每月15号都会触发。
  • L:表示最后,在DayofMonth域使用L,表示每个月的最后一天触发。
  • W:表示工作日,在DayofMonth域用15W,表示最接近这个月第15天的工作日触发,如果15号是周六,则在14号即周五触发;如果15号是周日,则在16号即周一触发;如果15号是周二则在当天触发。
    注意:该用法只会在当前月计算,不会到下月触发。比如在DayofMonth域用31W,31号是周日,那么会在29号触发而不是下月1号。在DayofMonth域用LW,表示这个月的最后一个工作日触发。

Month(月份):域中可出现, - * /四个字符,以及1-12的整数或JAN-DEC的单词缩写
DayofWeek(星期):可出现, - * / ? L # C八个字符,以及1-7的整数或SUN-SAT 单词缩写,1代表星期天,7代表星期六

  • C:在DayofWeek域使用2C,表示在2日后的那一天触发,且每周的那天都会触发。比如当前是周一,那么每周三都会触发。
  • L :在DayofWeek域使用L,表示在一周的最后一天即星期六触发。在DayofWeek域使用5L,表示在一个月的最后一个星期四触发。
  • #:用来指定具体的周数,#前面代表星期几,#后面代表一个月的第几周,比如5#3表示一个月第三周的星期四。
  • ?:在无法确定是具体哪一天时使用,用于DayofMonth和DayofWeek域。例如在每月的20日零点触发1次,此时无法确定20日是星期几,写法如下:0 0 0 20 * ?;或者在每月的最后一个周日触发,此时无法确定该日期是几号,写法如下:0 0 0 ? * 1L

Year(年份):域中可出现, - * /四个字符,以及1970~2099的整数。该域可以省略,表示每年都触发。

三、Spring Task_Cron案例

含义表达式
每隔5分钟触发一次0 0/5 * * * *
每小时触发一次0 0 * * * *
每天的7点30分触发0 30 7 * * *
周一到周五的早上6点30分触发0 30 7 ? * 2-6
每月最后一天早上10点触发0 0 10 L * ?
每月最后一个工作日的18点30分触发0 30 18 LW * ?
2030年8月每个星期六和星期日早上10点触发0 0 10 ? 8 1,7 2030
每天10点、12点、14点触发0 0 10,12,14 * * *
朝九晚五工作时间内每半小时触发一次0 0 0/30 9-17 ? * 2-6
每周三中午12点触发一次0 0 12 ? * 4
每天12点触发一次0 0 12 * * *
每天14点到14:59每分钟触发一次0 * 14 * * *
每天14点到14:59每5分钟触发一次0 0/5 14 * * *
每天14点到14:05每分钟触发一次0 0-5 14 * * *
每月15日上午10:15触发0 15 10 15 * ?
每月最后一天的上午10:15触发0 15 10 L * ?
每月的第三个星期五上午10:15触发0 15 10 ? * 6#3

四、定时任务的使用

1.创建SpringBoot项目,在启动类开启定时任务。

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

2.编写定时任务类

@Component
public class MyTask {
  // 定时任务方法,每秒执行一次
  @Scheduled(cron="* * * * * *")
  public void task1() {
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    System.out.println(sdf.format(new Date()));
   }
}

五、@Scheduled的使用

@Scheduled写在方法上方,指定该方法定时执行。常用参数如下:

  • cron:cron表达式,定义方法执行的时间规则。
  • fixedDelay:任务立即执行,之后每隔多久执行一次,单位是毫秒,上一次任务结束后计算下次执行的时间。
// 立即执行,任务结束后每5秒执行一次
@Scheduled(fixedDelay=5000)
public void task1() throws InterruptedException {
  SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
  Thread.sleep(1000);
  System.out.println(sdf.format(new Date()));
}

  • fixedRate:任务立即执行,之后每隔多久执行一次,单位是毫秒,上一次任务开始后计算下次执行的时间。
// 立即执行,之后每5秒执行一次
@Scheduled(fixedRate=5000)
public void task2() throws InterruptedException {
  SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
  Thread.sleep(1000);
  System.out.println(sdf.format(new Date()));
}

  • initialDelay:项目启动后不马上执行定时器,根据initialDelay的值延时执行。
// 项目启动3秒后执行,之后每5秒执行一次。
@Scheduled(fixedRate=5000,initialDelay = 3000)
public void task3() throws InterruptedException {
  SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
  Thread.sleep(1000);
  System.out.println(sdf.format(new Date()));
}

六、多线程任务

Spring Task定时器默认是单线程的,如果项目中使用多个定时器,使用一个线程会造成效率低下。此时我们可以给Spring Task配置线程池。

@Configuration
public class SchedulingConfig implements SchedulingConfigurer {
  public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
   // 创建线程池
   taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
  }
}


总结

提示:这里对文章进行总结:

通过学习和使用 Spring Task,我们可以方便地实现定时任务,提高应用的自动化程度和效率。希望这篇博客对你有所帮助,让你在定时任务的开发中更加得心应手!如果你有任何问题或建议,欢迎留言讨论。

文章来源:https://blog.csdn.net/liubopro666/article/details/135385705
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。