@

一、前言介绍

定时任务是企业开发中很常用的,比如定时推送一些接口数据,在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. RocketMQ源码详解(消息存储、Consumer)

    消息存储 消息存储核心类 private final MessageStoreConfig messageStoreConfig; //消息配置属性 private final CommitLog c ...

  2. Google I/O 详细解读

    AI创业失败,可私聊经验教训分享... 当前我唯一每个月付费的模型是ChatGPT,但昨天看了Google I/O 后,默默的打开了支付界面,国外做模型基建的大厂真的足够卷! PS:本来这篇文章是懒得 ...

  3. QPlainTextEdit获取鼠标选中内容

    QPlainTextEdit获取鼠标选中内容 m_plainTextEdit是一个 QPlainTextEdit * 获取选中内容 QString selectStr = m_plainTextEdi ...

  4. SpringBoot启动类没有启动按钮,java文件变为灰色的解决策略

      今天在查看Spring Boot项目的时候发现自己的项目变成了上面这个样子,无法执行main函数. 解决方法(上述操作可以忽略):选择我们项目的pom文件,然后右键选择 Add as Maven ...

  5. JAVA实现读取最后几行日志

    JAVA实现读取最后几行日志 1. 背景 在项目框架设计中,针对系统产生的日志,有线上查看日志的需求.日志文件本身很大.线上查看时,开发人员只想了解当前系统产生的错误信息. 2. POM依赖 主要使用 ...

  6. windows系统应急

    Windows系统的应急响应主要关注在发生安全事件或攻击后,如何迅速采取措施恢复系统的正常运行并确保数据的安全性.应急响应的目标是减少系统受到攻击的损害.恢复操作以及防止类似事件的再次发生. 应急响应 ...

  7. 入库出库查询软件——qt

    miniMes系统操作说明 一:功能说明 主界面有扫描--查询两个界面,扫描界面如下 1:默认开启自动入库出库功能 2:右上角限制位数可根据需求设定二维码字符串的位数,设置完成后点击设定,弹窗设定成功 ...

  8. Web前端入门第 66 问:JavaScript 作用域应用场景(闭包)

    什么是作用域? 就像孙悟空给唐僧画个圈圈一样,这个圈圈就可以称之为作用域,这个比喻可能不太形象. 作用域和孙悟空的圈圈还是有点区别,作用域内部可以获得作用域外部的变量,而内部的变量无法逃逸到作用域外面 ...

  9. Oracle故障处理:分析Oracle数据库离奇的多快读慢

    我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢! 由于博客中有大量代码,通过页面浏览效 ...

  10. UFT 的三种方法获取时间