@

一、前言介绍

定时任务是企业开发中很常用的,比如定时推送一些接口数据,在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依赖:



pom.xml参考

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.springboot</groupId>
<artifactId>springboot-scheduler-task</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-scheduler-task</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

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; /**
* <pre>
* TaskSchedulerConfiguration
* </pre>
*
* <pre>
* @author mazq
* 修改记录
* 修改后版本: 修改人: 修改日期: 2020/07/20 13:57 修改内容:
* </pre>
*/
@Configuration
@EnableScheduling
public class TaskSchedulerConfiguration { }

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

2.4 单线程定时任务

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

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

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

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

  • fixedRate

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

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



代码例子:每个任务计划执行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配置文件,加上:



ps:当然,不做配置也是可以的,因为SpringBoot有做自动配置,自己不改配置的,就全部按照SpringBoot的自动配置(默认)

代码例子下载:code download

SpringBoot系列之使用Spring Task实现定时任务的更多相关文章

  1. spring task的定时任务突然断了

    spring定时任务只开启一个线程去工作也就是串行工作,定时调度任务出现阻塞导致线程终止 加上这个试试 <!-- <task:annotation-driven /> --> ...

  2. 【Spring Task】定时任务详解实例-@Scheduled

    Spring的任务调度,采用注解的形式 spring的配置文件如下,先扫描到任务的类,打开spirng任务的标签 <beans xmlns="http://www.springfram ...

  3. spring task:annotation-driven 定时任务

    1.配置文件加上<task:annotation-driven/> 2.要运行的方法前加上 @Scheduled(cron="0 00 12 1 * ?")  //每月 ...

  4. SpringBoot系列之从入门到精通系列教程

    对应SpringBoot系列博客专栏,例子代码,本博客不定时更新 Spring框架:作为JavaEE框架领域的一款重要的开源框架,在企业应用开发中有着很重要的作用,同时Spring框架及其子框架很多, ...

  5. Spring 使用介绍(十二)—— Spring Task

    一.概述 1.jdk的线程池和任务调用器分别由ExecutorService.ScheduledExecutorService定义,继承关系如下: ThreadPoolExecutor:Executo ...

  6. 任务调度 Spring Task 4(一)

    深入浅出spring task定时任务 在工作中有用到spring task作为定时任务的处理,spring通过接口TaskExecutor和TaskScheduler这两个接口的方式为异步定时任务提 ...

  7. SpringBoot系列:Spring Boot定时任务Spring Schedule

    Spring Schedule是Spring提供的定时任务框架,相较于Quartz,Schedule更加简单易用,在中小型应用中,对于大部分需求,Schedule都可以胜任. 一.Spring Sch ...

  8. SpringBoot系列——动态定时任务

    前言 定时器是我们项目中经常会用到的,SpringBoot使用@Scheduled注解可以快速启用一个简单的定时器(详情请看我们之前的博客<SpringBoot系列--定时器>),然而这种 ...

  9. java定时任务实现的几种方式(Timer、Spring Task、Quartz)

    Timer JDK自带的Timer类,允许调度一个TimerTask任务. Demo: /** * Timer测试类 */ public class TimerDemo { public static ...

  10. Spring Task定时任务的配置和使用详解

    spring中使用定时任务 1.基于xml配置文件使用定时任务 首先配置spring开启定时任务 <beans xmlns="http://www.springframework.or ...

随机推荐

  1. 解决git clone 速度慢问题比较赞的方法

    使用国内镜像,目前已知的GitHub国内镜像网站有github.com.cnpmjs.org和git.sdut.me. 在clone 某项目时候可将github.com替换为github.com.cn ...

  2. 记一次burp抓不到包的排查与处理

    ​ 一次遇到了burp上奇怪的bug.访问某个页面显示 No response received from remote server , ​ 但是使用 yakit 进行抓包之后发现网站可以正常抓包 ...

  3. 简单介绍下 Vue 2.x 中的几种生命周期钩子(Lifecycle Hooks)

    〇.前言 在使用 Element UI 框架(基于 Vue 2.x)开发应用时,理解 Vue 的生命周期钩子(Lifecycle Hooks)是非常重要的. 这些钩子函数可以在组件的不同阶段执行特定的 ...

  4. 2024牛客多校3A Bridging the Gap 2

    希望更丰富的展现?来我搭建的网站看看 Problem \(n\) 个人乘船过河,该船容纳人的上限为 \(R\),并且需要至少 \(L\) 个人才能操作.每次过河时所有人都需划船,使船上所有人的耐力值减 ...

  5. FastAPI安全认证:从密码到令牌的魔法之旅

    title: FastAPI安全认证:从密码到令牌的魔法之旅 date: 2025/06/02 13:24:43 updated: 2025/06/02 13:24:43 author: cmdrag ...

  6. 「Log」2023.8.25 小记

    序幕 到校同学都没来,先摆. 写博客,写啊,写啊. 改费用流板子. \(\color{royalblue}{P3381\ [模板]最小费用最大流}\) 板子. 痛心疾首,建边的时候费用边反边为负权边. ...

  7. 使用Logback实现不同微服务输出各自的日志文件

    找到logback-spring.xml配置文件,在里面使用如下配置 <!--定义策略日志文件的存储地址--><property name="logStrategy.pat ...

  8. 3. LangChain4j-RAG,实现简单的text-sql功能

    1. 简介 前两章我们讲了如何使用LangChain4J进行AI交互, 其中包括 使用ChatLanguageModel.ChatMessage.ChatMemory等底层组件进行灵活/自由的与AI交 ...

  9. String在内存中如何分布

    一.设计思想及原理 设计思想 1.字符串分配和其他的对象分配一样,耗费高昂的时间与空间代价,作为最基础的数据类型,大量频繁的创建字符串,极大程度地影响程序的性能. 2.JVM为了提高性能和减少内存开销 ...

  10. 浅析百万级分布式调度引擎——DAGScheduleX能做什么?

    公交车伴随着我们的日常生活已是随处可见,不同路线的公交车根据各自的时间表有序发出,到达站点,接上站台的乘客再缓缓驶向下一站--早高峰会有短区间的加班车,发车间隔也更短,夜半时分的班次则间隔更长.这一切 ...