锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. 在Spring boot项目中实现定时任务

在Spring boot项目中实现定时任务

0
  • 软件开发
  • 发布于 2024-08-16
  • 0 次阅读
黄健
黄健

本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net

 一. 在 Spring boot 项目中实现简单的定时任务: 

        在 Spring boot 项目中实现定时任务通常用 Spring 的 @Scheduled 注解来完成。

        示例:

        1. 首先,在 Spring boot 项目中创建一个定时任务类,例如:TaskScheduler:

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
 
@Component
public class TaskScheduler {
 
    // 每隔5秒执行一次任务
    @Scheduled(fixedRate = 5000)
    public void scheduledTask() {
        System.out.println("定时任务执行啦!");
    }
}

        2. 在启动类或者配置类上添加 @EnableScheduling 注解,以开启定时任务的支持:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
 
@SpringBootApplication
@EnableScheduling
public class MyApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

        3. 完成以上步骤后,当运行 Spring Boot 时,定时任务会按照 @Scheduled 注解中配置的时间间隔执行。

二. @Scheduled 注解:

        @Scheduled 注解是 Spring 框架中用于配置定时任务的注解之一。通过在方法上添加 @Scheduled 注解,可以指定方法在特定时间执行,或者以固定时间间隔执行。在使用 @Scheduled 时,可以指定多种参数,包括 fixedDelay(固定延迟时间执行),fixedRate(固定频率执行),cron 表达式(按照 cron 表达式规则执行)等,以满足不同的定时任务需求。

        @Scheduled 各个参数用法:

  1. fixedDelay:

    • 用法:@Scheduled(fixedDelay = 1000)
    • 解释:指定方法执行结束后延迟多久再次执行,单位为毫秒。
    • 示例:@Scheduled(fixedDelay = 5000) 表示每次任务执行结束后延迟 5 秒再次执行。
  2. fixedRate:

    • 用法:@Scheduled(fixedRate = 2000)
    • 解释:指定方法开始执行后多久再次执行,单位为毫秒。不关心方法执行时间长短,固定频率执行。
    • 示例:@Scheduled(fixedRate = 3000) 表示每隔 3 秒执行一次任务,不论任务执行时间长短。
  3. initialDelay:

    • 用法:@Scheduled(initialDelay = 5000, fixedRate = 2000)
    • 解释:指定首次执行任务的延迟时间,单位为毫秒。
    • 示例:@Scheduled(initialDelay = 10000, fixedRate = 3000) 表示首次执行任务将在 10 秒后,之后每隔 3 秒执行一次。
  4. cron:

    • 用法:@Scheduled(cron = "0 0 12 * * ?")
    • 解释:使用 cron 表达式来指定任务执行的时间规则。
    • 示例:@Scheduled(cron = "0 0/5 8-20 * * ?") 表示在每天的上午 8 点到晚上 8 点,每隔 5 分钟执行一次任务。

cron 表达式的各个字段及其含义:

  • 秒(Seconds):取值范围为 0-59。
  • 分钟(Minutes):取值范围为 0-59。
  • 小时(Hours):取值范围为 0-23。
  • 日期(Day of month):取值范围为 1-31。
  • 月份(Month):取值范围为 1-12 或使用英文缩写(如 JAN-DEC)。
  • 星期(Day of week):取值范围为 0-7 或使用英文缩写(SUN-SAT),其中 0 和 7 都表示星期日。

cron表达式的格式如下:

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
 
@Service
public class MyService {
 
    @Async
    public void doSomethingAsync() {
        // 异步执行的任务代码
    }
}

例如,如果要每天中午 12 点执行一次任务,可以使用如下的cron表达式:

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
 
@Configuration
@EnableAsync
public class AppConfig {
    // 配置信息
}

在上述表达式中,0 0 12 * * ?表示每天中午 12 点执行一次任务。在实际使用中,根据具体的需求可以灵活设置cron表达式来指定定时任务的执行时间。需要注意的是,cron表达式中不同字段之间用空格分隔,同时还可以使用通配符、区间等方式来设置更复杂的定时规则。

        在cron表达式中,可以使用一些特殊的符号来设置更复杂的定时规则。以下是常用的通配符和区间符号: 

  1. 通配符:

    • *:表示匹配任意值。例如,*在分钟字段表示每分钟都执行。
    • ?:仅用于日和星期字段,表示不指定具体值。
  2. 区间:

    • -:表示范围。例如,1-5在小时字段表示 1 点到 5 点之间每个整点触发。
    • /:表示步长。例如,0/5在秒字段表示每隔 5 秒执行一次。
  3. 列表:

    • ,:表示列表。可以指定多个值逗号分隔。例如,1,3,5在小时字段表示 1 点、3 点和 5 点各执行一次。
  4. 通配符和区间的结合:

    • 可以结合通配符和区间来设置更复杂的定时规则。例如,0 0 0 1-10 * ?表示在每个月的 1 号到 10 号的午夜零点触发。
  5. 工作日和非工作日:

    • W:表示最接近给定日期的工作日(周一至周五)。例如,15W在日字段表示离每月 15 号最近的工作日触发。
    • L:表示最后一天。例如,L在日字段表示每个月的最后一天触发。

三. 实现定时任务的异步执行: 

        为什么要实现异步执行定时任务?主要有以下优点:   

  1. 提高系统性能:

    • 异步执行可以避免因为同步执行而造成的阻塞,提高系统的并发能力和响应速度。通过异步执行,系统可以同时处理多个任务,充分利用系统资源,提升系统整体性能。
  2. 增强用户体验:

    • 异步执行可以确保用户操作的及时响应,避免因为任务耗时长而导致用户界面假死或响应缓慢的情况发生。用户在等待任务完成的过程中可以继续进行其他操作,提升用户体验。
  3. 任务解耦和模块化:

    • 通过异步执行,可以将任务之间的耦合度降低,实现任务的解耦和模块化。不同的任务可以独立执行,各自管理自己的状态和资源,提高系统的灵活性和可维护性。
  4. 提高系统稳定性:

    • 异步执行可以将任务的执行隔离开来,降低任务之间的相互影响,提高系统的稳定性和容错能力。即使某个任务执行失败,也不会对系统的整体运行造成严重影响。
  5. 资源管理和调度优化:

    • 通过异步执行,可以更好地管理系统资源,优化任务调度策略,提高系统的资源利用率和效率。合理安排任务的执行顺序和时间,可以更好地满足业务需求。

        实现定时任务异步执行的方法有多种,这里主要介绍使用 Spring Framework 中的 @Async 注解来实现异步执行定时任务,通过在方法上添加 @Async 注解,Spring 会在调用该方法时自动创建一个新的线程来执行该方法,从而实现异步执行。 

        代码示例:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 
@Configuration
public class AppConfig implements AsyncConfigurer {
 
    @Override
    @Bean
    public TaskExecutor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.initialize();
        return executor;
    }
}

        在使用 @Async 注解时,需要在 Spring 配置类或者启动类上添加 @EnableAsync 注解来启用对异步方法的支持,例如:

import org.springframework.scheduling.annotation.Async;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
@Service
public class MyService {
 
    @Async("getAsyncExecutor")
    public void doSomethingAsync() {
        // 异步执行的任务代码
    }
}

        当使用@Async注解时,Spring 会默认使用一个线程池来执行异步方法。这个线程池是由 Spring 自动配置的,默认情况下,它会使用一个SimpleAsyncTaskExecutor来执行异步方法。

        我们可以在 Spring 的配置类中创建一个TaskExecutor bean,并在使用@Async注解时指定要使用的线程池。下面是一个简单的示例:

@Async("threadPoolTaskExecutor")
    @Scheduled(cron = "0 0/30 * * * ?")
    public void GrabFileInformation() {
        dataService.getAllDataTASK();
        log.info("执行了抓取数据定时任务!");
    }

        在上面的示例中,我们创建了一个ThreadPoolTaskExecutor bean,并通过重写AsyncConfigurer接口的getAsyncExecutor()方法,返回我们自定义的线程池实例。在这个示例中,我们设置了线程池的核心线程数、最大线程数和队列容量,并将其初始化后返回给 Spring 容器。

        接着,我们可以在需要使用异步方法的地方,使用@Async注解并指定要使用的线程池。例如:

import org.springframework.scheduling.annotation.Async;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
@Service
public class MyService {
 
    @Async("getAsyncExecutor")
    public void doSomethingAsync() {
        // 异步执行的任务代码
    }
}

        在上面的示例中,我们在doSomethingAsync方法上使用了@Async("getAsyncExecutor")注解,指定了要使用的线程池名为getAsyncExecutor,这样就可以使用我们自定义的线程池来执行异步方法了。

        那么要实现定时任务的异步执行就很简单了,例如:

@Async("threadPoolTaskExecutor")
    @Scheduled(cron = "0 0/30 * * * ?")
    public void GrabFileInformation() {
        dataService.getAllDataTASK();
        log.info("执行了抓取数据定时任务!");
    }

        记得在配置类上加上 @EnableAsync 和 @EnableScheduing 注解即可。

标签: #Spring Boot 173 #软件开发 1171 #JAVA 991
相关文章

万字:支付“核心系统”详解 2024-11-02 15:33

专栏作者:隐墨星辰 \| 主编:陈天宇宙 这篇文章也尝试化繁为简,探寻支付系统的本质,讲清楚在线支付系统最核心的一些概念和设计理念。 虽然支付行业已经过了风头最劲的时光,但跨境支付仍然在蓬勃发展,每年依然有很多新人进入这个行业,这篇文章尝试为这些刚入行的新人提供一点帮助。 文章只介绍一些支付行业十几

资深支付架构师视角:实战从问题定义到代码落地的完整套路 2024-11-02 15:33

前言 今天从一个实际案例入手,介绍站在架构师的角度,如何识别并定义问题,提炼需求,技术方案选型,再到详细设计,最后利用AI的能力协助写出核心的代码,验证与调优。 解决问题存在一定的模式,也可以称之为框架,总结出自己的思考和解题框架,以后再碰到同类型的问题就可以如庖丁解牛一样容易。 很多年前,我写代码

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

设计模式第16讲——迭代器模式(Iterator) 2024-10-08 11:24

一、什么是迭代器模式 迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式访问集合中的元素。 二、角色组成 抽象迭代器(Iterator):定义了遍历聚合对象所需的方法

vue2路由和vue3路由区别及原理 2024-10-08 11:24

一、Vue2 与 Vue3 路由的区别 1. 创建路由实例方式的不同 Vue 2 中,通过 Vue.use() 注册路由插件,并通过 new VueRouter() 来创建路由实例。 import Vue from 'vue';import VueRouter from 'vue-router';i

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.