如何在springboot中使用定时任务

在日常的开发过程中经常使用到定时任务,在springMVC的开发中,经常和quartz框架进行集成使用,但在springboot中没有这么做,而是使用了java的线程池来实现定时任务。

一、概述

在springboot中使用定时任务非常简单,只需要简单的几步即可完成。

二、详述

在springboot中要使用定时任务,首先要保证环境是springboot的,这里使用的是springboot-2.1.2.release版本。在启动类上加@EnableScheduling注解,如下,

package com.example.demo;

import com.example.demo.properties.ApplicationPro;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableConfigurationProperties({ApplicationPro.class})
//引入开启定时任务的注解
@EnableScheduling
public class DemoApplication {

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }

}

@EnableScheduling注解的作用就是开启对定时任务的支持,这个注解的作用是开启定时任务的自动配置。

在使用了@EnableScheduling注解后便可以编写具体的定时任务的job类,该job类无需继承或实现任何接口,只要是一个被spring管理的类即可。为了使spring可以管理统一使用@Component注解标识。在定时任务的类中的方法上标识@Scheduled注解便可以定时执行该方法,@Scheduled注解上有几种不同的属性,看具体的该注解的定义,

fixedDelay

@Scheduled(fixedDelay=1000)/@Scheduled(fixedDelay="1000")的意思是该方法执行完后每隔1000ms执行一次。看具体的代码

package com.example.demo.job;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class SchedulFixedRelayTest {

  //@Scheduled(fixedDelay = 5000)
  public void jobTest(){

    try {
      log.info("使用fixedDelay的定时任务");
      Thread.sleep(10*1000);

    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }

}

看执行结果,

2020-12-09 22:02:47.511 INFO 7368 --- [      main] o.s.web.context.ContextLoader      : Root WebApplicationContext: initialization completed in 940 ms
2020-12-09 22:02:47.681 INFO 7368 --- [      main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-12-09 22:02:47.782 INFO 7368 --- [      main] o.s.s.c.ThreadPoolTaskScheduler     : Initializing ExecutorService 'taskScheduler'
2020-12-09 22:02:47.802 INFO 7368 --- [  scheduling-1] c.e.demo.job.SchedulFixedRelayTest    : 使用fixedDelay的定时任务
2020-12-09 22:02:47.820 INFO 7368 --- [      main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-12-09 22:02:47.823 INFO 7368 --- [      main] com.example.demo.DemoApplication     : Started DemoApplication in 1.627 seconds (JVM running for 2.51)
2020-12-09 22:03:02.819 INFO 7368 --- [  scheduling-1] c.e.demo.job.SchedulFixedRelayTest    : 使用fixedDelay的定时任务
2020-12-09 22:03:17.834 INFO 7368 --- [  scheduling-1] c.e.demo.job.SchedulFixedRelayTest    : 使用fixedDelay的定时任务

看上面打印的执行时间,第一次在2020-12-09 22:02:47,由于程序会睡眠10秒,也就是说回在22:02:57执行完,那么下次执行应该在22:03:02,看第二次打印的时间刚好和上面的一样,那就证明了,该配置是在方法执行完成后每隔XX秒执行一次。

fixedRate

@Scheduled(fixedRate=1000)/@Scheduled(fixedRate="1000")的意思是该方法执行完后每隔1000ms执行一次,但是如果任务执行的时间超过了配置的时间,则在任务执行完会再次执行。

任务时间小于配置的时间

package com.example.demo.job;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class SchedulFixedRateTest {

  @Scheduled(fixedRate = 5000)
  public void jobTest(){

    try {
      log.info("使用fixedRate的定时任务");
      Thread.sleep(1*1000);

    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }

}

任务会睡眠1s也就是任务耗时1s,fixedRate配置的是每隔5s,由于任务时间小于配置的时间,所以会每隔5s执行一次,看执行结果,

2020-12-09 22:16:16.156 INFO 2800 --- [  scheduling-1] c.example.demo.job.SchedulFixedRateTest : 使用fixedRate的定时任务
2020-12-09 22:16:16.188 INFO 2800 --- [      main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-12-09 22:16:16.188 INFO 2800 --- [      main] com.example.demo.DemoApplication     : Started DemoApplication in 1.625 seconds (JVM running for 2.462)
2020-12-09 22:16:21.178 INFO 2800 --- [  scheduling-1] c.example.demo.job.SchedulFixedRateTest : 使用fixedRate的定时任务
2020-12-09 22:16:26.180 INFO 2800 --- [  scheduling-1] c.example.demo.job.SchedulFixedRateTest : 使用fixedRate的定时任务

看打印的任务时间都是每隔5s执行一次。

任务时间大于配置的时间

看任务的执行时间打印配置的时间的情况,

package com.example.demo.job;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class SchedulFixedRateTest {

  @Scheduled(fixedRate = 5000)
  public void jobTest(){

    try {
      log.info("使用fixedRate的定时任务");
      Thread.sleep(10*1000);

    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }

}

这里任务执行10s,配置的时间为5s。看执行结果,

2020-12-09 22:17:44.070 INFO 12952 --- [  scheduling-1] c.example.demo.job.SchedulFixedRateTest : 使用fixedRate的定时任务
2020-12-09 22:17:44.102 INFO 12952 --- [      main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-12-09 22:17:44.102 INFO 12952 --- [      main] com.example.demo.DemoApplication     : Started DemoApplication in 1.626 seconds (JVM running for 2.462)
2020-12-09 22:17:54.071 INFO 12952 --- [  scheduling-1] c.example.demo.job.SchedulFixedRateTest : 使用fixedRate的定时任务
2020-12-09 22:18:04.085 INFO 12952 --- [  scheduling-1] c.example.demo.job.SchedulFixedRateTest : 使用fixedRate的定时任务

从上面的结果可以看到任务是每隔10s执行一次,由于任务耗时大于了配置的时长,所以任务执行完以后便会进入下次的执行。

cron

cron表达式共7位,分别是秒、分、小时、日、月、周、年。cron表达式可以从网上找,如下,

https://cron.qqe2.com/

通过cron在线生成,分别设置值,如,0/5 * * * * ?  每隔5s执行一次,

package com.example.demo.job;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class SchedulCronTest {

  @Scheduled(cron = "0/5 * * * * ?")
  public void jobTest(){

    try {
      log.info("使用cron的定时任务");
      Thread.sleep(10*1000);

    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }

}

每隔5s执行一次,任务耗时10s,看下执行结果,

2020-12-09 22:41:42.718 INFO 17828 --- [      main] com.example.demo.DemoApplication     : Started DemoApplication in 1.609 seconds (JVM running for 2.453)
2020-12-09 22:41:45.015 INFO 17828 --- [  scheduling-1] com.example.demo.job.SchedulCronTest   : 使用cron的定时任务
2020-12-09 22:42:00.004 INFO 17828 --- [  scheduling-1] com.example.demo.job.SchedulCronTest   : 使用cron的定时任务
2020-12-09 22:42:15.000 INFO 17828 --- [  scheduling-1] com.example.demo.job.SchedulCronTest   : 使用cron的定时任务

可以看到是每隔15s执行一次,也就是如果配置的时间间隔小于任务耗时,那么在任务执行完后的时间间隔后再执行,在此种情况下和fixDelay的用法一致。

三、总结

本文分析了springboot中定时任务的使用,

首先,使用@EnableScheduling开启定时任务的自动配置;

其次,任务类必须受spring管理(使用@Component、@Service等注解均可);

最后,任务方法使用@Scheduled注解标识,该注解有3中不同的属性配置,fixedDelay、fixedRate、cron;

以上就是如何在springboot中使用定时任务的详细内容,更多关于springboot中使用定时任务的资料请关注我们其它相关文章!

(0)

相关推荐

  • SpringBoot集成Quartz实现定时任务的方法

    1 需求 在我的前后端分离的实验室管理项目中,有一个功能是学生状态统计.我的设计是按天统计每种状态的比例.为了便于计算,在每天0点,系统需要将学生的状态重置,并插入一条数据作为一天的开始状态.另外,考虑到学生的请假需求,请假的申请往往是提前做好,等系统时间走到实际请假时间的时候,系统要将学生的状态修改为请假. 显然,这两个子需求都可以通过定时任务实现.在网上略做搜索以后,我选择了比较流行的定时任务框架Quartz. 2 Quartz Quartz是一个定时任务框架,其他介绍网上也很详尽.这里要介

  • 一篇文章教你使用SpringBoot如何实现定时任务

    前言 在 Spring + SpringMVC 环境中,一般来说,要实现定时任务,我们有两中方案,一种是使用 Spring 自带的定时任务处理器 @Scheduled 注解,另一种就是使用第三方框架 Quartz ,Spring Boot 源自 Spring+SpringMVC ,因此天然具备这两个 Spring 中的定时任务实现策略,当然也支持 Quartz,本文我们就来看下 Spring Boot 中两种定时任务的实现方式. 一.第一种方式:@Scheduled 使用 @Scheduled

  • SpringBoot整合SpringTask实现定时任务

    半藏商城中会有一些用户提交了订单但是一直没有支付的情况,之前我是通过quartz定时任务每天的5点扫描未支付订单然后读取用户的邮箱地址发送邮件提醒用户尽快支付.这次我是采用Spring中自带的SpringTask来进行定时任务. Cron表达式 Cron表达式是一个字符串,包括6~7个时间元素,在SpringTask中可以用于指定任务的执行时间. Cron的语法格式 Seconds Minutes Hours DayofMonth Month DayofWeek Cron格式中每个时间元素的说明

  • 浅谈springboot项目中定时任务如何优雅退出

    在一个springboot项目中需要跑定时任务处理批数据时,突然有个Kill命令或者一个Ctrl+C的命令,此时我们需要当批数据处理完毕后才允许定时任务关闭,也就是当定时任务结束时才允许Kill命令生效. 启动类 启动类上我们获取到相应的上下文,捕捉相应命令.在这里插入代码片 @SpringBootApplication /**指定mapper对应包的路径*/ @MapperScan("com.youlanw.kz.dao") /**开启计划任务*/ @EnableScheduling

  • SpringBoot定时任务参数运行代码实例解析

    @Scheduled注解各参数详解  cron 该参数接收一个cron表达式,cron表达式是一个字符串,字符串以5或6个空格隔开,分开共6或7个域,每一个域代表一个含义. cron表达式语法 [秒] [分] [小时] [日] [月] [周] [年] 注:[年]不是必须的域,可以省略[年],则一共6个域 序号 说明 必填 允许填写的值 允许的通配符 1 秒 是 0-59 , - * / 2 分 是 0-59 , - * / 3 时 是 0-23 , - * / 4 日 是 1-31 , - *

  • springboot+quartz以持久化的方式实现定时任务的代码

    这篇文章给大家介绍springboot+quartz以持久化的方式实现定时任务,详情如下所示: 篇幅较长,耐心的人总能得到最后的答案小生第一次用quartz做定时任务,不足之处多多谅解. 首先 在springboot项目里做定时任务是比较简单的,最简单的实现方式是使用**@Scheduled注解,然后在application启动类上使用@EnableScheduling**开启定时任务. 示例 @SpringBootApplication @EnableScheduling public cla

  • Springboot定时任务Scheduled重复执行操作

    今天用scheduled写定时任务的时候发现定时任务一秒重复执行一次,而我的cron表达式为 * 0/2 * * * * . 在源码调试的过程中,发现是我的定时任务执行过程太短导致的. 于是我另外写了个简单的定时任务 @Component public class TestJob { @Scheduled(cron = "* 0/2 * * * *") public void test() { System.out.println("测试开始"); System.o

  • springBoot 创建定时任务过程详解

    前言 好几天没写了,工作有点忙,最近工作刚好做一个定时任务统计的,所以就将springboot 如何创建定时任务整理了一下. 总的来说,springboot创建定时任务是非常简单的,不用像spring 或者springmvc 需要在xml 文件中配置,在项目启动的时候加载.spring boot 使用注解的方式就可以完全支持定时任务. 不过基础注解的话,可能有的需求定时任务的时间会经常变动,注解就不好修改,每次都得重新编译,所以想将定时时间存在数据库,然后项目读取数据库执行定时任务,所以就有了基

  • Springboot非分布式定时任务实现代码

    1. 核心注解 在springboot项目中我们可以很方便地使用spring自己的注解@Scheduled和@EnableScheduling配合来实现便捷开发定时任务. @EnableScheduling注解的作用是发现注解@Scheduled的任务并后台执行,此注解可以加到启动类上也可以加到执行调度任务类上. 经测试,当有多个包含定时任务的类时,@EnableScheduling注解加在其中一个类上就可以保证所有定时任务的成功实现. 注意:定时任务的类上还需要配合使用@Configurati

  • springboot如何配置定时任务

    概述 在Java环境下创建定时任务有多种方式: 使用while循环配合 Thread.sleep(),虽然稍嫌粗陋但也勉强可用 使用 Timer和 TimerTask 使用 ScheduledExecutorService 定时任务框架,如Quartz 在SpringBoot下执行定时任务无非也就这几种方式(主要还是后两种).只不过SpringBoot做了许多底层的工作,我们只需要做些简单的配置就行了. 通过注解实现定时任务 在SpringBoot中仅通过注解就可以实现常用的定时任务.步骤就两步

  • springboot实现多实例crontab抢占定时任务(实例代码)

    github: https://github.com/jiasion/eslog wechat:minghui-666 利用redisson实现多实例抢占定时任务 pom.xml <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.12.0</version> </dependency>

随机推荐