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)

大家都在看

  • 接口偶尔超时,竟又是JVM停顿的锅!

    原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。 简介 继上次我们JVM停顿十几秒的问题解决后,我们系统终于稳定了,再也不会无故重启了!这是之前的文章…

    Java 2023年6月7日
    069
  • java 文件打压缩包下载

    项目中需要将多个文件打包成压缩包下载。 总共文件是,一个从磁盘读取的文件,其他文件通过url从oss下载的文件, @GetMapping("/export/{id}&qu…

    Java 2023年6月13日
    061
  • Java: Mediator Pattern

    java;gutter:true; /<em><em> * 版权所有 2022 涂聚文有限公司 * 许可信息查看: * 描述: * 中介者模式/调停者模式 …

    Java 2023年6月16日
    066
  • 手把手带你使用Paint in 3D和Photon撸一个在线涂鸦画板

    Paint in 3D Paint in 3D用于在游戏内和编辑器里绘制所有物体。所有功能已经过深度优化,在WebGL、移动端、VR 以及更多平台用起来都非常好用! 它支持标准管线…

    Java 2023年6月7日
    079
  • 工具开发的层次成本价值

    工具开发在软件开发中应用的层次 成本 价值 一:工具在软件中的应用。 工欲善其事,必先利其器。一款优良的开发工具是高效的完成开发工作的基础。根据公司项目状况,自定义工具开发是提高公…

    Java 2023年6月8日
    075
  • 【Java面试】面试如何让面试官面的很爽,看完这道面试题,finally块一定会执行吗?

    “finally块一定会执行吗?”这是最近一个工作3年的小伙伴去面试的时候遇到的问题。你遇到这个问题会怎么回答呢?大家好,我是Mic,一个工作了14年的Ja…

    Java 2023年6月16日
    081
  • 关于数据拓展及面试题讲解 Java

    强类型语言 要求变量的使用严格符合规定,所有变量都必须先定义后才能使用 弱类型语言 Java 的数控类型分为两大类 基本类型(primitive type ) 引用类型(refer…

    Java 2023年6月5日
    063
  • 设计模式之建造者模式

    在有些情况下,一个对象会有一些重要的性质,在他们没有被赋值之前,对象不能作为一个完整的产品使用。比如,一个电子邮件有发件人地址、收件人地址、主题、内容、附件等,最起码在收件人地址没…

    Java 2023年6月5日
    085
  • Linux命令tar的压缩与解压

    tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只…

    Java 2023年6月7日
    062
  • SpringMVC 解析(一)概览

    Spring MVC是Spring提供的构建Web应用程序的框架,该框架遵循了Servlet规范,负责接收并处理Servelt容器传递的请求,并将响应写回Response。Spri…

    Java 2023年6月8日
    079
  • Spring Boot 整合Hibernate Validator

    Spring Boot 整合Hibernate Validator 代码仓库: https://github.com/Rain-with-me/JavaStudyCode/tree…

    Java 2023年6月16日
    053
  • 玩转SpringBoot之定时任务@Scheduled线程池配置

    序言 对于定时任务,在SpringBoot中只需要使用@Scheduled 这个注解就能够满足需求,它的出现也给我们带了很大的方便,我们只要加上该注解,并且根据需求设置好就可以使用…

    Java 2023年5月30日
    0130
  • RabbitMQ 工作队列

    每日一句 如果你执意追逐我的幻影,迟早会被真正的我打败。 https://www.ylcoder.top/post/1649241412 概述 工作队列(又称任务队列)的主要思想是…

    Java 2023年6月9日
    098
  • 如何解决VMware 虚拟机不能铺满屏幕

    出现这种情况是因为分辨率设置问题,调整分辨率总能达到你想要的效果; 首先设置vmware为全屏模式 查看物理机的分辨率,然后再将虚拟机的分辨率设置了跟物理机的一致。完美解决 win…

    Java 2023年5月30日
    0164
  • 使用spire.doc导出支持编辑Latex公式的标准格式word

    背景 之前有的教辅标注需求,在导出题库的时候希望顺便导出可以查看word,方便线下预览成品效果,因为只是用来预览并且为了沿用前端的样式,当时方案就是直接生成html,写个word的…

    Java 2023年6月7日
    061
  • 抽象类

    抽象类 当父类的一些方法不能确定时,可以用abstract关键字来修饰该方法,这个方法就是抽象方法,用abstract来修饰该类就是抽象类。 * 即:父类方法不确定性的问题 * =…

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