Spring Boot定时任务

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

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>

开启定时任务:

c36e6505c0204960a18ab008c0778bab.png

任务内容:

c3f8f33cfd9642e2987cde6be7715ad2.png

2.2.cron表达式

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

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

秒(0-59)

分钟(0-59)

小时(0-23)

日(1-31)

月(1-12或JAN-DEC)

周几(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。

image.png

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 {
    @Autowired
    private 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的定时任务底层其实就是使用线程池来实现的,其流程如下:

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


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


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


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


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

5.自定义线程池

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

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


目录
相关文章
|
7月前
|
druid Java 数据库
Spring Boot的定时任务与异步任务
Spring Boot的定时任务与异步任务
|
7月前
|
Java 数据库 Spring
Spring Boot 实现定时任务的动态增删启停
Spring Boot 实现定时任务的动态增删启停
100 0
|
4月前
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
定时任务在企业应用中至关重要,常用于异步数据处理、自动化运维等场景。在单体应用中,利用Java的`java.util.Timer`或Spring的`@Scheduled`即可轻松实现。然而,进入微服务架构后,任务可能因多节点并发执行而重复。Spring Cloud Alibaba为此发布了Scheduling模块,提供轻量级、高可用的分布式定时任务解决方案,支持防重复执行、分片运行等功能,并可通过`spring-cloud-starter-alibaba-schedulerx`快速集成。用户可选择基于阿里云SchedulerX托管服务或采用本地开源方案(如ShedLock)
134 1
|
2月前
|
Java BI 调度
Java Spring的定时任务的配置和使用
遵循上述步骤,你就可以在Spring应用中轻松地配置和使用定时任务,满足各种定时处理需求。
153 1
|
2月前
|
存储 Java API
简单两步,Spring Boot 写死的定时任务也能动态设置:技术干货分享
【10月更文挑战第4天】在Spring Boot开发中,定时任务通常通过@Scheduled注解来实现,这种方式简单直接,但存在一个显著的限制:任务的执行时间或频率在编译时就已经确定,无法在运行时动态调整。然而,在实际工作中,我们往往需要根据业务需求或外部条件的变化来动态调整定时任务的执行计划。本文将分享一个简单两步的解决方案,让你的Spring Boot应用中的定时任务也能动态设置,从而满足更灵活的业务需求。
128 4
|
5月前
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
Spring Cloud Alibaba 发布了 Scheduling 任务调度模块 [#3732]提供了一套开源、轻量级、高可用的定时任务解决方案,帮助您快速开发微服务体系下的分布式定时任务。
15020 33
|
7月前
|
NoSQL Java Redis
Spring Boot 监听 Redis Key 失效事件实现定时任务
Spring Boot 监听 Redis Key 失效事件实现定时任务
144 0
|
4月前
|
Java 开发者 Spring
Spring Boot实战宝典:揭秘定时任务的幕后英雄,让业务处理如流水般顺畅,轻松驾驭时间管理艺术!
【8月更文挑战第29天】在现代应用开发中,定时任务如数据备份、报告生成等至关重要。Spring Boot作为流行的Java框架,凭借其强大的集成能力和简洁的配置方式,为开发者提供了高效的定时任务解决方案。本文详细介绍了如何在Spring Boot项目中启用定时任务支持、编写定时任务方法,并通过实战案例展示了其在业务场景中的应用,同时提供了注意事项以确保任务的正确执行。
53 0
|
4月前
|
Dubbo Java 调度
揭秘!Spring Cloud Alibaba的超级力量——如何轻松驾驭分布式定时任务调度?
【8月更文挑战第20天】在现代微服务架构中,Spring Cloud Alibaba通过集成分布式定时任务调度功能解决了一致性和可靠性挑战。它利用TimerX实现任务的分布式编排与调度,并通过`@SchedulerLock`确保任务不被重复执行。示例代码展示了如何配置定时任务及其分布式锁,以实现每5秒仅由一个节点执行任务,适合构建高可用的微服务系统。
72 0
|
5月前
|
SQL Java 调度
实时计算 Flink版产品使用问题之使用Spring Boot启动Flink处理任务时,使用Spring Boot的@Scheduled注解进行定时任务调度,出现内存占用过高,该怎么办
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。