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)

大家都在看

  • nginx使用与配置入门指南

    这是一篇关于nginx使用与配置的入门指南,但不包括nginx的编译与安装。我假定你知晓如何安装nginx。对大多数Linux系统来说,nginx都已经存在于它们的软件包里,直接使…

    Java 2023年5月30日
    096
  • 从零开始实现lmax-Disruptor队列(四)多线程生产者MultiProducerSequencer原理解析

    在v3版本的MyDisruptor实现多线程消费者后。按照计划,v4版本的MyDisruptor需要支持线程安全的多线程生产者功能。 由于该文属于系列博客的一部分,需要先对之前的博…

    Java 2023年6月8日
    080
  • JAVAEE学习路线分享

    今天把我的教学经验分享给大家。适合大多数人的学习路线。注:目前作者已经转行做java培训。 首先是培养兴趣。先开始学习HTML知识。也就是做网页,从这里开始比较简单,就是几个标签单…

    Java 2023年6月9日
    098
  • iphone 开发学习笔记七

    本篇算是该系列最后一篇,虽不能说是很熟,但使用MonoTouch 开发的其本方法是掌握了,主要是完成当初的任务,实现地图开发包在iPhone上的实现。使用MonoTouch ,.N…

    Java 2023年5月29日
    052
  • nginx负载均衡高可用

    1.1 什么是负载均衡高可用 nginx作为负载均衡器,所有请求都到了nginx,可见nginx处于非常重点的位置,如果nginx服务器宕机后端web服务将无法提供服务,影响严重。…

    Java 2023年5月30日
    098
  • 如何使用 RSA 加密 JWT

    <dependency> <groupid>com.nimbusds</groupid> <artifactid>nimbus-jo…

    Java 2023年6月7日
    097
  • 使用ocupload和POI一键上传Excel并解析导入数据库

    使用的工具如下: JQuery ocupload jquery.ocupload-1.1.2.js Apache POI poi-3.9.jar 如果是Maven项目添加依赖如下:…

    Java 2023年6月5日
    0110
  • golang并发编程中select关键字的使用

    golang并发编程中select关键字的使用 select的使用类似于switch语句,有case和default分支。其中每个case对应一个通道的通信过程: 1、select…

    Java 2023年6月13日
    072
  • 4.MySQL动态拼接

    举例如下: posted @2022-09-06 23:07 NIANER2011 阅读(7 ) 评论() 编辑 Original: https://www.cnblogs.com…

    Java 2023年6月13日
    084
  • Grafana 安装

    环境 CentOS 8 1. 安装 sudo nano /etc/yum.repos.d/grafana.repo 写入配置 [grafana] name=grafana base…

    Java 2023年6月9日
    081
  • 基本数据类型-java学习日记

    1.不同进制的数据组成 二进制: 由0,1组成。以0b开头 八进制: 由0,1,…7组成。以0开头 十进制:由0,1,…9组成。整数默认是十进制 十六进制:…

    Java 2023年6月5日
    098
  • Mysql索引学习笔记

    https://www.jianshu.com/p/ace3cd6526c4 &#x63A8;&#x8350;up&#x4E3B;https://space…

    Java 2023年6月14日
    0176
  • elasticsearch 7.7.0 最新版+Java High Level REST Client测试

    服务端:elasticsearch 7.7.0 Docker部署 客户端:spring boot +thymeleaf+Java High Level REST Client 7….

    Java 2023年5月29日
    092
  • Day16自定义异常

    package com.exception.demo02;//自定义的异常类public class MyException extends Exception{ //传递数字&g…

    Java 2023年6月5日
    086
  • Vue初探

    MVVM模型 M:模型(Model) :对应 data 中的数据 V:视图(View) :模板(理解为html页面) VM:视图模型(ViewModel) : Vue 实例对象 数…

    Java 2023年6月9日
    079
  • 说说用户线程和守护线程

    什么是用户线程和守护线程? 守护线程是一种特殊的线程,在后台默默地完成一些系统性的服务,比如 垃圾回收线程、 JIT线程都是 守护线程。与之对应的是 用户线程,用户线程可以理解为是…

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