SpringBoot系列之使用Spring Task实现定时任务

@

一、前言介绍

定时任务是企业开发中很常用的,比如定时推送一些接口数据,在java中实现定时任务的方法有Spring Task、Quartz等等框架,也有JDK自带的ScheduledExecutorService、Timer

Quartz框架比较复杂,之前我写过一个入门教程,读者可以参考学习:Quartz系列之任务调度框架原理简介

Spring Task是Spring3.0以后自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多

二、Spring Task

2.1 SpringTask简介

Spring Task不是独立的项目,是spring-context 模块下提供的定时任务工具,是Spring3.0以后自带的task,可以将它看成一个轻量级的Quartz

2.2 实验环境准备

  • JDK 1.8
  • SpringBoot2.2.1
  • Maven 3.2+
  • 开发工具
  • IntelliJ IDEA
  • smartGit

创建一个SpringBoot Initialize项目,详情可以参考我之前博客:SpringBoot系列之快速创建项目教程

SpringBoot项目引入spring-boot-starter-web既可,因为wen场景启动器会自动引入spring-context依赖:

SpringBoot系列之使用Spring Task实现定时任务
pom.xml参考

    4.0.0

        org.springframework.boot
        spring-boot-starter-parent
        2.2.1.RELEASE

    com.example.springboot
    springboot-scheduler-task
    0.0.1-SNAPSHOT
    springboot-scheduler-task
    Demo project for Spring Boot

        1.8

            org.springframework.boot
            spring-boot-starter-web

            org.projectlombok
            lombok
            true

            org.springframework.boot
            spring-boot-starter-test
            test

                    org.junit.vintage
                    junit-vintage-engine

                org.springframework.boot
                spring-boot-maven-plugin

2.3 Enable Scheduling

开启Spring Scheduling必须使用@EnableScheduling注解,可以新建一个配置类,然后加上注解

package com.example.springboot.scheduler.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;

/**
 *
 *      TaskSchedulerConfiguration
 *
 *
 *
 * @author mazq
 * 修改记录
 *    修改后版本:     修改人:  修改日期: 2020/07/20 13:57  修改内容:
 *
 */
@Configuration
@EnableScheduling
public class TaskSchedulerConfiguration {

}

也可以像官网例子一样,加在application类:

SpringBoot系列之使用Spring Task实现定时任务

2.4 单线程定时任务

Spring Task使用定时任务,只要加上@Scheduled注解,然后也要加到Spring容器中,使用可以加上@Service等注解就可以,Scheduled策略:cron 、fixedDelay、fixedRate 三选一

ok,下面介绍@Scheduled的4个关键属性

意思是:在上一次调用的结束与下一次调用的开始之间以固定的毫秒数为单位执行带注释的方法。

ps:这种策略比较好理解,意思就是不管任务执行时间,只关注时间间隔就可以,画图表示:

SpringBoot系列之使用Spring Task实现定时任务
  • fixedRate

SpringBoot系列之使用Spring Task实现定时任务

意思是: 两次调用之间以固定的时间段(以毫秒为单位)执行带注释的方法。

这种策略先预计任务执行时间,fixedRate参数指定,画图描述,如图,fixedRate=10000(10s):

SpringBoot系列之使用Spring Task实现定时任务
代码例子:每个任务计划执行5s
@Scheduled( fixedRate = 5000)
    public void testFixedRate() {
        log.info("fixedRate test,thread name:[{}],execute time:[{}]",Thread.currentThread().getName(),
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
    }
  • cron
    cron参数是用cron表达式的意思,cron表达式含义:

Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义。

用表格表示Cron表达式:

位置 时间域 允许值 特殊值 1 秒 0-59 ,- * / 2 分钟 0-59 ,- * / 3 小时 0-23 ,- * / 4 日期 1-31 ,- * ? / L W C 5 月份 1-12 ,- * / 6 星期 1-7 ,- * ? / L C # 7 年份(可选) 1-31 ,- * / 特殊字符 代表含义 , 枚举,表达一个列表值,如在星期字段中使用”MON,WED,FRI”,则表示星期一,星期三和星期五; – 区间 ,表达一个范围,如在小时字段中使用”10-12″,则表示从10到12点,即10,11,12; * 任意,可用在所有字段中,表示对应时间域的每一个时刻,例如, 在分钟字段时,表示”每分钟”; / 步长,x/y表达一个等步长序列,x为起始值,y为增量步长值。如在分钟字段中使用0/15,则表示为0,15,30和45秒,而5/15在分钟字段中表示5,20,35,50,你也可以使用*/y,它等同于0/y; ? 该字符只在日期和星期字段中使用,它通常指定为”无意义的值”,相当于点位符; L 该字符只在日期和星期字段中使用,代表”Last”的意思,但它在两个字段中意思不同。L在日期字段中,表示这个月份的最后一天,如一月的31号,非闰年二月的28号;如果L用在星期中,则表示星期六,等同于7。但是,如果L出现在星期字段里,而且在前面有一个数值X,则表示”这个月的最后X天”,例如,6L表示该月的最后星期五; W 工作日,该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。例如15W表示离该月15号最近的工作日,如果该月15号是星期六,则匹配14号星期五;如果15日是星期日,则匹配16号星期一;如果15号是星期二,那结果就是15号星期二。但必须注意关联的匹配日期不能够跨月,如你指定1W,如果1号是星期六,结果匹配的是3号星期一,而非上个月最后的那天。W字符串只能指定单一日期,而不能指定日期范围; C 该字符只在日期和星期字段中使用,代表”Calendar”的意思。它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。例如5C在日期字段中就相当于日历5日以后的第一天。1C在星期字段中相当于星期日后的第一天。 # 该字符只能在星期字段中使用,表示当月某个工作日。如6#3表示当月的第三个星期五(6表示星期五,#3表示当前的第三个),而4#5表示当月的第五个星期三,假设当月没有第五个星期三,忽略不触发; LW LW组合,在日期字段可以组合使用LW,它的意思是当月的最后一个工作日;

每隔1分钟执行一次:

@Scheduled(cron = "0 0/1 * * * ? ")
    public void testCron(){
        log.info("cron test,thread name:[{}],execute time:[{}]",Thread.currentThread().getName(),
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

  • initialDelay
    initialDelay 初始化延迟时间,也就是标识第一次延迟执行的时间,只能配合 fixedDelay 或 fixedRate 使用
@Scheduled(initialDelay = 5000, fixedRate = 5000)
    public void testFixedRate() {
        log.info("fixedRate test,thread name:[{}],execute time:[{}]",Thread.currentThread().getName(),
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
    }

2.5 线程池的使用配置

配置文件加上代码,配置线程池

@Bean
    public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
        threadPoolTaskScheduler.setPoolSize(5);
        threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler");
        threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);
        threadPoolTaskScheduler.setAwaitTerminationSeconds(60);
        return threadPoolTaskScheduler;
    }

也可以在application配置文件,加上:

SpringBoot系列之使用Spring Task实现定时任务
ps:当然,不做配置也是可以的,因为SpringBoot有做自动配置,自己不改配置的,就全部按照SpringBoot的自动配置(默认)

代码例子下载:code download

Original: https://www.cnblogs.com/mzq123/p/13360748.html
Author: smileNicky
Title: SpringBoot系列之使用Spring Task实现定时任务

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/541220/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • MySQL 优化篇(一)

    本次项目演示基于MySQL 官方提供的测试库下载到本地后,解压执行:mysql -uroot -p -t < employees.sql 即可!测试库表关系 MySQL 数据…

    Java 2023年6月8日
    0104
  • 【JAVA基础】别人的开源项目结构

    https://www.bilibili.com/read/cv5236887 posted on2020-08-19 23:18 tigerloveapple 阅读(82 ) 评…

    Java 2023年5月29日
    084
  • Flutter Pub发布失败

    csharp;gutter:true; Do you want to publish rome_bus 0.0.2 (y/N)? y Uploading… (1.3s) Fai…

    Java 2023年5月29日
    069
  • Eureka

    Spring Cloud 服务注册中心 1 注册中心的主要作用 服务注册中心(也称注册中心)是微服务架构非常重要的一个组件,在微服务架构里主要起到了协调者的一个作用。注册中心-般包…

    Java 2023年6月8日
    071
  • SpringBoot 2.x 开发案例之前后端分离鉴权

    前言 阅读本文需要一定的前后端开发基础,前后端分离已成为互联网项目开发的业界标准使用方式,通过 Nginx&#x4EE3;&#x7406;+Tomcat的方式有效的…

    Java 2023年5月30日
    079
  • 进程、线程、协程、例程、过程的区别是什么?

    400 Bad Request: 无效的请求。抱歉,给您带来麻烦了! 麻烦您发邮件至 contact@cnblogs.com 向我们反馈。 返回网站首页 Original: htt…

    Java 2023年5月30日
    089
  • 叫练手把手教你读JVM之GC信息

    众所周知,GC主要回收的是堆内存,堆内存中包含年轻代和老年代,年轻代分为Eden和Surivor,如下图所示。我们用案例分析下堆的GC信息【版本: HotSpot JDK1.8】。…

    Java 2023年6月8日
    070
  • SpringBoot使用自定义注解+AOP+Redis实现接口限流

    为什么要限流 系统在设计的时候,我们会有一个系统的预估容量,长时间超过系统能承受的TPS/QPS阈值,系统有可能会被压垮,最终导致整个服务不可用。为了避免这种情况,我们就需要对接口…

    Java 2023年6月16日
    075
  • Sharepoint 2013 安装部署系列篇 第三篇 — 安装和配置网络负载均衡在前端web服务器

    第一部分 系统集群安装 第二部分 SQL集群安装 第四部分 安装和配置sharepoint 场(三层拓扑部署) 接下来一步一步开始配置NLB吧, 以下开始讲解如何配置NLB集群作为…

    Java 2023年6月7日
    0163
  • Java–使用多线程下载,断点续传技术原理(RandomAccessFile)

    一.基础知识 1.什么是线程?什么是进程?它们之间的关系? 可以参考之前的一篇文章:java核心知识点学习—-并发和并行的区别,进程和线程的区别,如何创建线程和线程的四…

    Java 2023年5月29日
    079
  • Java 实现等频分箱

    等频离散法 Python 实现方式 Java 实现方式 测试结果对比 总结 等频离散法 根据数据的频率分布进行排序,然后按照频率进行离散,好处是数据变为均匀分布,但是会更改原有的数…

    Java 2023年6月9日
    0116
  • python爬虫配置IP代理池(ProxyPool)

    关注我的公众号【靠谱杨的挨踢生活】回复 ProxyPool可以免费获取网盘链接。也可自行搜索下载:https://github.com/Python3WebSpider/Proxy…

    Java 2023年6月15日
    094
  • 控制反转,依赖注入,依赖倒置傻傻分不清楚?

    通过这篇文章,你将了解到 控制反转(IoC)是什么?「反转」到底反转了什么? Spring和IOC之间是什么关系? 依赖注入(DI)和依赖倒置原则(DIP)又是什么? IOC、DI…

    Java 2023年6月7日
    0101
  • 循环结构(Java)

    基本介绍 while循环语法 while(&#x5E03;&#x5C14;&#x8868;&#x8FBE;&#x5F0F;){&#x…

    Java 2023年6月9日
    064
  • Unity应用架构设计(10)——绕不开的协程和多线程(Part 2)

    在上一回合谈到,客户端应用程序的所有操作都在主线程上进行,所以一些比较耗时的操作可以在异步线程上去进行,充分利用CPU的性能来达到程序的最佳性能。对于Unity而言,又提供了另外一…

    Java 2023年5月30日
    080
  • Java7之后的intern

    最近在《深入理解Java虚拟机》一书中了解到,以下内容在Java7中第一个返回true,第二个返回false,产生了一些疑惑,经过一番搜索,对intern的理解有所加深,这里记一下…

    Java 2023年5月29日
    082
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球