Spring Boot定时任务

目录

1.概述

2.Spring Boot定时任务

2.1.快速使用

2.2.cron表达式

3.业务示例

3.1.业务描述

3.2.业务实现

4.实现原理

5.自定义线程池


1.概述

在某些业务场景中,需要定时执行一些任务,有可能是定时统计然后生成报表,有可能是定时发起一个任务。最近在工作中就正好遇见一个定时发起问卷任务的一个业务场景,此处集合业务场景聊聊如何用spring boot来实现功能。

2.Spring Boot定时任务

2.1.快速使用

spring boot支持了定时任务,通过很简单的配置就可以使用。

依赖:

定时任务是spring boot框架提供的基础能力之一,所以其依赖是在spring-boot-starter里面,但是一般开发的时候我们直接引入web依赖即可,web依赖中包含了spring-boot-starter。要注意的是Spring Boot 从版本1.3.0开始提供对定时任务的支持,本文用的依赖默认是支持定时任务的版本。

<dependencies><!-- Spring Boot Web Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>

开启定时任务:

任务内容:

2.2.cron表达式

spring boot中是使用cron表达式来定义定时任务的执行条件的。cron表达式由6个字段组成,分别表示秒、分、时、日、月、周几。每个字段都可以接受特定的取值范围或通配符来表示时间的匹配规则。

下面是cron表达式的每个字段的含义和可接受的取值:

  1. 秒(0-59)
  2. 分钟(0-59)
  3. 小时(0-23)
  4. 日(1-31)
  5. 月(1-12或JAN-DEC)
  6. 周几(0-7或SUN-SAT,其中0和7都表示周日)

除了具体的取值范围,cron表达式还支持一些特殊字符和符号:

  • 星号(*):表示匹配任意值。例如,使用星号在秒字段中,表示任务在每一秒都会被触发。
  • 问号(?):仅在日期和周几字段中使用,表示不指定具体的值。如果你想在日期字段中匹配任意值,但同时又想在周几字段中指定具体值,就可以使用问号。
  • 斜线(/):用于指定增量。例如,在分钟字段中使用5/10,表示从第5分钟开始,每隔10分钟触发一次。
  • 逗号(,):用于列举多个值。例如,在周几字段中使用1,3,5,表示任务在周一、周三和周五触发。
  • 连接符(-):用于指定范围。例如,在小时字段中使用9-17,表示任务在9点到17点之间触发。

以下是一些示例cron表达式的用法:

  • 0 0 0 * * *:每天凌晨执行任务
  • 0 0/5 * * * *:每隔5分钟执行任务
  • 0 0 9-17 * * MON-FRI:周一至周五的9点到17点之间每小时执行任务

3.业务示例

3.1.业务描述

需求:

  • 管理人员新建一个问卷调查任务,任务在固定时间发起,固定时间结束。
  • 任务开始后,系统的每个用户会收到一份问卷
  • 任务结束后,用户不可再答题

实体关系:

整个实体关系很简单,就是一个任务一种模板,一个任务多份问卷,一个模板N份问卷,一个问卷一个用户。

问卷里记录了模板内容、任务ID、用户ID。

3.2.业务实现

问卷调查任务类:

这里使用JPA去访问数据库

@Entity
@Table(name = "survey_task")
public class SurveyTask {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String taskName;private LocalDateTime startTime;// 其他属性和对应的getter/setter方法
}

定时任务:

这里只是简单的写了一下定时任务的逻辑,实际的代码实现从简。

@Service
public class SurveyTaskScheduler {@Autowiredprivate SurveyTaskRepository surveyTaskRepository;@Scheduled(cron = "0 0 0 * * *") // 每天凌晨执行public void distributeSurveyTemplates() {LocalDate today = LocalDate.now();LocalDateTime startOfDay = today.atStartOfDay();List<SurveyTask> surveyTasks = surveyTaskRepository.findByStartTime(startOfDay);for (SurveyTask task : surveyTasks) {// 根据任务分发问卷模板给用户的逻辑// ...System.out.println("分发问卷模板给用户: " + task.getTaskName());}}
}

启动定时任务:

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

4.实现原理

spring boot的定时任务底层其实就是使用线程池来实现的,其流程如下:

  1. 首先,Spring Boot 根据配置文件中的属性创建一个 TaskScheduler(如果没有自定义线程池会使用默认线程池ThreadPoolTaskScheduler)实例作为调度器,并设置线程池的相关属性,例如核心线程数、最大线程数、队列容量等。

  2. 当应用启动时,Spring Boot 会扫描所有被 @Scheduled 注解标记的方法,并将这些方法注册为定时任务。

  3. 当定时任务的触发条件满足时,调度器将从线程池中选择一个线程来执行任务。

  4. 执行任务时,调度器会通过 TaskExecutor(默认为 ThreadPoolTaskExecutor)实例来执行任务。它会从线程池中选择一个空闲的线程来执行被 @Scheduled 注解标记的方法。

  5. 执行完成后,线程将返回到线程池中等待下一次调度。

5.自定义线程池

如果在 Spring Boot 中没有显式配置线程池,那么会使用默认的线程池配置。但是有时候可能我们也需要自定义线程池,自定义线程池的示例如下:

@Configuration
public class CustomThreadPoolConfig {@Beanpublic TaskScheduler taskScheduler() {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.setPoolSize(10); // 设置线程池大小// 设置其他线程池属性,如队列容量、线程名前缀等return scheduler;}
}


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/42.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个好看美观的登录注册界面的实现

序言&#xff1a;之前介绍那个博客&#xff0c;然后自己搞了这个界面。最近有人和我要&#xff0c;把代码给大家贴出来&#xff0c;提供参考。 首先是这个界面哈 <!DOCTYPE html> <html lang"en"> <head><script src"../static/lib/jquer…

mac本地创建ssh key连接github

起因 今天克隆自己github上面的笔记到新电脑上&#xff0c;用http连接进行克隆&#xff0c;然后要我输入账号密码&#xff0c;输入完报了个提示“remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.”…

XHbuilder 需要的 ipa 签名,超详细的教程,你不看吃亏的是自己!

今天使用 hbuilder 运行到 ios 真机的时候&#xff0c;突然发现还需要 ipa 签名&#xff0c;这是什么东东呢&#xff1f; 1、IPA 签名是什么&#xff1f; 因苹果公司禁止企业证书用于非企业内部开发者。所以开发者无法再使用DCloud的企业证书签名的标准运行基座。 运行标准基…

享元模式:减少内存占用的诀窍

一&#xff0c;概要 享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构型设计模式&#xff0c;它主要通过共享对象来降低系统中对象的数量&#xff0c;从而减少内存占用和提高程序性能。这听起来有点像单例模式&#xff0c;但它们在实现和用途上有很大的区别。享元…

web前端求职面试题参考精选(合集)

web前端求职面试题之选择题 1. CSS样式表根据所在网页的位置&#xff0c;可分为?(B ) A.行内样式表、内嵌样式表、混合样式表 B.行内样式表、内嵌样式表、外部样式表 C.外部样式表、内嵌样式表、导入样式表 D.外部样式表、混合样式表、导入样式表 2. 对于标签&#xff0…

01 | 一条 SQL 查询语句是如何执行的?

以下内容出自 《MySQL 实战 45 讲》 一条 SQL 查询语句是如何执行的&#xff1f; 下面是 MySQL 的基本架构示意图&#xff0c;从中可以清楚地看到 SQL 语句在 MySQL 的各个功能模块中的执行过程。 大体来说&#xff0c;MySQL 可以分为 Server 层和存储引擎层两部分。 Server …

较旧系统的轻量级的LINUX发行版—FATDOG64

导读我们回顾FatDog64 Linux&#xff0c;这个轻量级的Linux发行版可能不是现代的&#xff0c;但它非常适合于老化的计算机&#xff0c;fatdog64 Linux是一个小而灵活的64位多用户Linux发行版。 有一个Linux发行版几乎每一个都需要&#xff0c;有Linux分布的黑客&#xff0c;天…

Jenkins在Ubuntu的安装问题

使用apt安装没有成功&#xff0c;各种报错。最后使用了离线安装方式。 1、安装jdk。和之前的安装jdk无异&#xff0c;增加一步 添加一个软链接 sudo ln -s /path/to/java/home/bin/java /usr/bin/java 2、下载deb包&#xff0c;然后安装 2.1、前置步骤&#xff0c;安装可能…

点击向数组中添加对象,并判断是否已经包含了重复值

需求&#xff1a;现在有一堆列表&#xff0c;当我每次点击列表的每一项时&#xff0c;希望将此项添加到一个数组中&#xff0c;并且已添加的数据不能再添加 效果图 实现&#xff1a; <!DOCTYPE html> <html lang"zh"> <head><meta charset&quo…

kafka3.x 入门 安装(一)

一、下载地址 http://kafka.apache.org/downloads.html 二、 zookeeper安装教程 https://blog.csdn.net/weixin_43205308/article/details/130426019 三、解压 这里使用的是kafka_2.12-3.0.0.tgz tar -zvxf kafka_2.12-3.0.0.tgz四、修改配置 进入到安装路径的config文件夹下…

chatgpt赋能python:Python选择排序最简单的写法是什么?

Python选择排序最简单的写法是什么&#xff1f; 选择排序是一种简单的排序算法&#xff0c;通常用于小规模数据集的排序。Python是一种广泛使用的脚本语言&#xff0c;也可以用来实现选择排序算法。这篇文章将介绍Python选择排序的最简单写法&#xff0c;并分析其优缺点。 选…

Android设计模式—桥接模式

1.桥接模式 桥接模式是一种结构型设计模式&#xff0c;它通过将抽象部分与实现部分分离来解耦。它使用接口作为桥梁&#xff0c;将一个抽象类与其实现类的代码独立开来&#xff0c;从而使它们可以各自独立地变化。桥接模式的核心思想是“组合优于继承”。 简单来讲&#xff0…