实战讲解Spring定时任务:@Scheduled(图+文+源码)

news2024/11/24 12:50:10

1 缘起

最近看到有些定时任务的项目,
使用了Spring自带的定时任务系统,通过添加@Scheduled注解的方式实现,
并且,使用了不只cron表达式的方式实现定时执行,
恍然大悟,原来@Scheduled还有其他的方式实现定时任务,
于是,看了下@Scheduled的源码,发现有三类参数供开发者使用,cron、fixedDelay和fixedRate,同时,复习了一下cron表达式,
分享如下,帮助读者进一步了解@Scheduled的使用,轻松应对知识交流与知识考核。
版本:Spring-Context:5.2.7.RELEASE

2 注解:@Scheduled

2.1 是什么

先看下注解的注释,如下图所示。
位置:org.springframework.scheduling.annotation.Scheduled
由注释可知,
(1)注解@Scheduled标注在方法上实现定时功能;
(2)使用注解时必须指定任意一个参数(属性):cron、fixedDelay或fixedRate;
(3)注解标识的方法必须时无参方法且无返回值。如果有返回值,返回值会被忽略;
(4)有两种方式生效该注解:XML中配置:task:annotaion-driven,或者使用注解:@EnableScheduling;
(5)定时任务的相关逻辑在:ScheduledAnnotationBeanPostProcessor(org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor)。
在这里插入图片描述

2.2 功能

(1)定时执行任务:指定执行的星期、月、天、时、分、秒,定时执行任务,cron参数;
(2)固定周期执行任务:间隔x毫秒周期性指定任务,fixRate参数;
(3)固定间隔延迟执行任务:延迟x毫秒执行指定任务,fixDelay参数。

2.3 参数分析

2.3.1 CRON_DISABLED

常量参数CRON_DISABLED,用于配置未生效定时任务,
值为:-,如果已经配置了定时任务,但是,不想启用定时任务,则配置cron为-
在这里插入图片描述
在ScheduledAnnotationBeanPostProcessor中使用该参数,用于判断cron表达式是否生效。
具体的方法为processScheduled,处理逻辑如下图所示,
由图可知,检查cron表达式,如果cron表达式为-,则该定时任务,不会被添加到任务池。
位置:org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor#processScheduled

在这里插入图片描述

2.3.2 cron

CRON类型的表达式,配置定时任务,共有6个时间粒度,
参数样式:a b c d e f
从左到右分别表示:
秒、分、小时、天、月、星期。

序号参数取值范围特殊字符
1[0, 59]* , - /
2分钟[0, 59]* , - /
3小时[0, 23]* , - /
4日期[1, 31]* , - / ? L W
5[1, 12]或[JAN, DEC]* , - /
6星期[1,7]或[MON, SUN]* , - / ? L #

特殊字符

序号特殊字符描述样例
1*所有可能的值如在分钟的位置配置*,表示每一分钟都生效
2,枚举值表示对应的数据,如分钟位置配置10,20,30,表示在某点的10分、20分和30分执行
3-范围间隔值1,左右的数据表示上界和下界,如分钟位置配置:10-20,表示某点10分和20分之间,每1分钟执行
4/增量左侧数据表示起始值,右侧数据表示增量,分钟位置配置:3/10,表示从第一个间隔3分钟后,每10分钟执行,秒位置:2/10,表示从第一个2秒后开始,每10秒执行
5?不指定在日期或星期中使用,为避免冲突,将另一个位置配置?
6LLast,最后一个日期位置使用L表示最后一天,星期位置使用L表示最后一个星期的最后一天
7W除周末以外的有效工作日日期位置就近原则,如果5W,5日在为星期六,则在4日执行,如果5日是星期日,则在星期一执行,如果5日在周一~周五,则在5日当天执行
8#确定每个月第几个星期几,仅支持星期星期位置,4#2表示某月的第二个星期四

如配置为:0/5 * * * * ?,表示每5秒执行一次。
参数描述如下图所示,
有一行描述为:如果配置为-则不会触发定时任务。
在这里插入图片描述

2.3.3 fixDelay

延迟固定时间执行:服务启动后,延迟固定的时间执行该任务,此后定期执行以此间隔作为执行周期。
参数描述如下图所示,
由图可知,有两种类型long和String,其中,long类型的单位为毫秒。
在这里插入图片描述

2.3.4 fixRate

固定周期执行:以固定的时间执行该任务。
参数描述如下图所示,
由图可知,有两种类型long和String,其中,long类型的单位为毫秒。
在这里插入图片描述

2.3.5 initialDelay

首次执行fixRate和fixedDelay延迟的时间,时间单位:毫秒。
参数源码如下图所示。
在这里插入图片描述

2.4 实际应用

2.4.1 cron样例

着重看下cron样例:

序号配置描述
10/5 * * * * ?每5秒执行一次
20 0/2 * * * ?每两分钟执行一次
30 2 3 1 * ?每月1日3点2分执行一次
40 2 3 1 1-3 ?1月到3月的:1日3点2分执行一次
50 0 2,3,4,5 * * ?每天2点、3点、4点和5点执行一次
60 10 2 * * ?每天2:10分执行一次
0 0-5 14,16 * * ?每天14:00到14:55和16:00到16:55每5分钟执行一次
0 10 10 L * ?每月最后一天的10:10执行一次
0 10 10 5W * ?每月的工作日5日10:10分执行,如果5日为周六,则往前退一天(星期五),4日10:10执行,如果5日为星期日,则往后推一天(星期一),6日10:10日执行
0 10 10 ?* 4#2每月的第二个星期四10:10执行一次

2.4.2 测试样例

  • 生效定时任务
    在启动类中添加@EnableScheduling。
package com.monkey.standalone;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

import javax.annotation.Resource;

/**
 * 启动类.
 *
 * @author xindaqi
 * @date 2021-04-30 18:22
 */
@SpringBootApplication
@EnableScheduling
public class StandaloneApplication {

	private static final Logger logger = LoggerFactory.getLogger(StandaloneApplication.class);
	public static void main(String[] args) {
		SpringApplication.run(StandaloneApplication.class, args);
		logger.info("Standalone启动成功");
	}
}
  • 定时任务
package com.monkey.standalone.common.schedule;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 定时任务样例.
 *
 * @author xindaqi
 * @since 2022-11-30 23:04
 */
@Component
public class DemoSchedule {

    private static final Logger logger = LoggerFactory.getLogger(DemoSchedule.class);

    /**
     * CRON周期性任务:如从第一个10秒后,每隔5秒执行
     * 参数顺序:
     * 秒-分-时-日-月-周
     */
    @Scheduled(cron="10/5 * * * * ?")
    public void cronSchedule() {
        logger.info(">>>>>>>>Cron schedule:{}", LocalDateTime.now());
    }

    /**
     * 延迟固定时间周期性执行(从服务启动后开始)
     * 服务启动时间:10:30,任务在10:33开始执行,
     * 此后以3秒为周期执行
     */
    @Scheduled(fixedDelay = 3000)
    public void fixedDelaySchedule() {
        logger.info(">>>>>>>>FixedDelay schedule:{}", LocalDateTime.now());
    }

    /**
     * 固定周期执行
     * 固定每4秒执行一次
     */
    @Scheduled(fixedRate = 4000)
    public void fixedRateSchedule() {
        logger.info(">>>>>>>>FixedRate schedule:{}", LocalDateTime.now());
    }

    /**
     * 首次延迟周期性执行,
     * 服务启动后,延迟2秒执行,
     * 此后,每3秒执行一次
     */
    @Scheduled(initialDelay = 2000, fixedRate = 3000)
    public void initialDelaySchedule() {
        logger.info(">>>>>>>>InitialDelay and FixedRate schedule:{}", LocalDateTime.now());
    }
}

测试结果如下图所示,详见图中描述。

在这里插入图片描述

3 小结

(1)注解@Scheduled标注在方法上实现定时功能;
(2)使用注解时必须指定任意一个参数(属性):cron、fixedDelay或fixedRate;
(3)注解标识的方法必须时无参方法且无返回值。如果有返回值,返回值会被忽略;
(4)有两种方式生效该注解:XML中配置:task:annotaion-driven,或者使用注解:@EnableScheduling;
(5)定时任务的相关逻辑在:ScheduledAnnotationBeanPostProcessor。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/80169.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《小猫猫大课堂》3之字符串,转义字符,注释,选择和循环语句,函数等小概括。

更新不易,麻烦多多点赞,欢迎你的提问,感谢你的转发, 最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!! 喵喵喵,你对我…

这十套练习,教你如何用Pandas做数据分析(01)

Pandas是入门Python做数据分析所必须要掌握的一个库。本文内容由和鲸社区翻译整理自Github,建议读者完成科赛网 从零上手Python关键代码 和 Pandas基础命令速查表 教程学习的之后,点击本篇Notebook右上角的 Fork 按钮对本教程代码进行调试学习。 转载本…

(附源码)SSM的KTV管理系统 毕业设计 291807

基于SSM的KTV管理系统 摘 要 随着社会的发展,人类的进步,21世纪人们的生活水平有所提高,为了满足人们对生活的需要,丰富业余生活,娱乐KTV等行业蓬勃发展,在数字化的今天,我们已离不开计算机&…

Redis的面试题

一、Redis支持的数据类型? Redis支持的数据类型主要有五种:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorte…

opencv图像特征

图像特征类型可以分为如下三种: 边缘角点(感兴趣关键点)斑点(感兴趣区域) 其中,角点是个很特殊的存在。如果某一点在任意方向的一个微小变动都会引起灰度很大的变化,我们就把它称之为角点。角点…

17、Redis6.0新功能

文章目录17、Redis6.0新功能17.1 ACL17.1.1 简介17.1.2 命令17.2 IO多线程17.2.1 简介17.2.2 原理架构17.3 工具支持 Cluster17.4 Redis新功能持续关注Redis 6 入门到精通-讲师:王泽 世态炎凉,世界并不善良 17、Redis6.0新功能 17.1 ACL 17.1.1 简介 …

如何利用场追迹控制衍射的包含

1. 摘要 VirtualLab Fusion包括一系列建模方法便于用户可以地调整光学仿真的精度级别和时间。不仅如此,这种功能还有助于隔离物理原因产生的不同影响。在本示例中,我们提出了一个清晰的工作流程配置一个仿真,以便在物理光学模拟中考虑或忽略衍…

MOSFET 和 IGBT 栅极驱动器电路的基本原理学习笔记(六)变压器耦合栅极驱动

变压器耦合栅极驱动 1.单端变压器耦合栅极驱动电路 2.双端变压器耦合栅极驱动 在高电压栅极驱动 IC 出现以前,使用栅极驱动变压器是唯一一种在离线或类似高电压电路中驱动高侧开关的可行解决方案。 现在,两种解决方案同时存在并且各有利弊,…

基础数据结构线性表

基础数据结构 1.基础概念 数据结构是一种具有一定逻辑关系,在计算机中应用某种存储结构,并且封装了相应操作的数据元素的集合。它包含三方面的内容,逻辑关系、存储关系以及操作。 一般而言,数据结构的选择首先会从抽象数据类型…

springboot整合Canal实时同步数据库表

一、Canal介绍 1、应用场景 在前面的统计分析功能中,我们采取了服务调用获取统计数据,这样耦合度高,效率相对较低,目前我采取另一种实现方式,通过实时同步数据库表的方式实现,例如我们要统计每天注册与登…

语雀的技术栈与富文本编辑讨论分享

目录前言什么是语雀富文本编辑器的发展历程语雀结构简析语雀核心语雀渲染器语雀前端技术业务层编辑器语雀编辑器演化过程语雀研发流程关于语雀的讨论为何文档编写不是一种标准化的中台能力内容类产品典型类别业务所需编辑器开发成本如何?文本编辑器代码编辑器公式编…

[附源码]Python计算机毕业设计SSM基于的网上拍卖系统(程序+LW)

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

13.javase_动漫美女拼图实战

资料地址:https://cowtransfer.com/s/4573fe572f9c4a 项目效果: 练习编程逻辑思维,提高和锻炼自己能力。 一. 绘制游戏界面 1.1窗体绘制 第一个方法:initFrame(),用于窗体的基本设置 public void initFrame() { thi…

每天一个面试题:悲观锁、乐观锁,对比Hashtable和concurrentHashMap

每天一个面试题:悲观锁、乐观锁Hashtable和concurrentHashMap总结开始全新的学习,沉淀才会有产出,一步一脚印! 面试题系列搞起来,这个专栏并非单纯的八股文,我会在技术的基础上,Debug解析&#…

戴维南定理(Thevenin‘s theorem)

戴维南定理:含独立电源的线性电阻单口网络N,就端口特性而言,可以等效为一个电压源和电阻串联的单口网络。电压源的电压等于单口网络在负载开路时的电压uoc;电阻R0是单口网络内全部独立电源为零值时所得单口网络N0的等效电阻。 例子…

JavaScript基本语法

1.JavaScript词法结构 所谓词法结构是指一套基础性规则,用来描述如何使用这门语言来编写程序,包括如下几项: 字符集unicode 区分大小写 (true和TRUE) 忽略空白字符(空格、制表符和换行符&#xff09…

UG鼠标和键盘操作

UG鼠标和键盘操作角色操作鼠标操作选择放大/缩小旋转平移确认适合窗口正视于X/Y/Z视图显示样式九宫图设置键盘操作ESCF8角色操作 角色包含了用户的自定义配置,包括内容、演示、快捷键、工具栏等,通过:菜单-首选项-用户界面-角色 进行导入导出…

【C语言程序设计】实验 8

目录 1. 整数排序 2. 二维数组按每行数据之和升序 3. 字符串排序 4. 二维数组各行元素之和 5. 二位整数数组交换两行 6. 插入排序 7. 10进制转2进制&#xff0c;8进制和16进制数&#xff08;数组&#xff09; 1. 整数排序 【问题描述】从键盘输入n(0<n<21)个整…

微服务同时接入多个Kafka

准备工作 自己搭建一个Kafka 从官方下载Kafka&#xff0c;选择对应Spring Boot 的版本&#xff0c;好在Kafka支持的版本范围比较广&#xff0c;当前最新版本是3.2.1,支持2.12-3.2.1 范围的版本&#xff0c;覆盖了Spring Boot 2.0x-Spring Boot 3.0.x。Apache Kafka 解压安装 …

CMake中target_compile_definitions的使用

CMake中的target_compile_definitions命令用于向target添加编译定义&#xff0c;其格式如下&#xff1a; target_compile_definitions(<target><INTERFACE|PUBLIC|PRIVATE> [items1...][<INTERFACE|PUBLIC|PRIVATE> [items2...] ...]) 指定在编译给定的<…