添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
【Spring Boot系列】如何动态地设置定时任务的时间?

【Spring Boot系列】如何动态地设置定时任务的时间?

大家好,我是 @明人只说暗话

禁止白嫖哦!
点赞、评论、关注,总要选择一个吧!

本文和大家聊聊定时任务相关的话题,定时任务是后端项目中很常见的一个应用场景。

对于大型新项目来说,一般都有单独的调度系统,甚至是分布式调度系统,通过xxl-job、elastic job、SchedulerX或quartz等调度组件,来支撑项目中大量的定时任务。

对于小项目来说,没必要单独搞一个调度系统,通过Spring的Scheduled注解就可以快速实现定时任务。

用过Scheduled注解的朋友应该知道,一旦我们通过cron属性、fixedDelay或者fixedRate属性指定定时任务指定的时间之后,就没法再改变了。

想要改变定时任务的时间就要修改配置文件,重启项目。

但,项目是我们想要重启就能重启的吗?

显然不是!

因此,我们要寻找一种可以动态设置定时任务的时间的方案,来代替Scheduled注解。

本文就为大家提供两种解决方案,让你可以在项目中随心所欲的动态地修改定时任务的时间。

首先,我们简单了解一下Scheduled注解。

Scheduled注解

一般都是通过Spring的Scheduled注解,通过cron属性指定定时任务的时间,通过fixedDelay或者fixedRate属性指定定时任务的固定延迟或固定速率。

将cron表达式或者固定延迟或固定速率定义在配置文件中,虽然能够很好的完成定时任务,却不能在项目运行中动态地修改任务执行时间,总体来说,不太灵活。

package com.panda.scheduler.scheduler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Component
@Slf4j
public class TestScheduler {
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    @Scheduled(cron = "${scheduler.sendEmailCron}")
    public void sendEmail() {
        log.info("定时任务开始时间: {}", LocalDateTime.now().format(DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS)));
        try {
            // 定时任务具体业务逻辑,模拟业务逻辑处理
            log.info("定时任务具体业务逻辑,模拟业务逻辑处理......");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            log.error("发送邮件定时任务处理失败", e);
            Thread.currentThread().interrupt();
        log.info("定时任务结束时间: {}", LocalDateTime.now().format(DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS)));
}

对上面的例子来说,定时任务可以正常按照我们设置的时间执行。

但是,当我们因为各种原因,需要修改这个定时任务的时间的时候,就只能修改配置文件,然后重新启动项目了,比较麻烦。

再者,爱情不是你想买就能买,项目不是你想重启就能重启的!

下面,我们就通过两个例子为大家介绍如何动态地设置定时任务的时间。

代码示例一:CronTrigger触发器

application.yml配置文件

server:
  port: 8080
  servlet:
    context-path: /
scheduler:
  # 发送邮件定时任务的时间每5秒执行一次
  sendEmailCron: 0/5 * * * * ?

在配置文件中,配置各个定时任务的时间。

SchedulerDemoApplication

package com.panda.scheduler;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication




    
;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class SchedulerDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SchedulerDemoApplication.class, args);

入口类。

注意@EnableScheduling注解,该注解启用Spring的定时任务功能。

SendEmailScheduler定时任务类

package com.panda.scheduler.scheduler;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Component
@Slf4j
@Getter
@Setter
public class SendEmailScheduler implements SchedulingConfigurer {
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    @Value("${scheduler.sendEmailCron}")
    private String sendEmailCron;
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        // 使用cron表达式可以动态地设置循环间隔
        taskRegistrar.addTriggerTask(() -> {
            log.info(">>>>>>定时任务开始时间: {}", LocalDateTime.now().format(DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS)));
            try {
                // 定时任务具体业务逻辑,模拟业务逻辑处理
                log.info("定时任务具体业务逻辑,模拟业务逻辑处理......");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                log.error("发送邮件定时任务处理失败", e);
                Thread.currentThread().interrupt();
            log.info(">>>>>>定时任务结束时间: {}", LocalDateTime.now().format(DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS)));
        }, triggerContext -> {
            // 使用CronTrigger触发器,可动态修改cron表达式来操作循环规则
            CronTrigger cronTrigger = new CronTrigger(sendEmailCron);
            return cronTrigger.nextExecutionTime(triggerContext);

发送邮件定时任务类。

该类实现了SchedulingConfigurer接口,实现configureTasks方法。

在configureTasks方法中,一是执行具体的业务逻辑(本例中是发送邮件),二是实现触发器接口,用于确定与其关联的任务的下一次执行时间,简单说就是 设置定时任务下次执行的时间

既然可以设置定时任务的下次执行的时间,那我们在应用运行的过程中,在不重新部署应用的情况下,如果能改变定时任务的时间,不就可以实现动态修改定时任务时间的功能了嘛!

下面,我们就实现实现动态修改定时任务时间的功能,也就是暴露一个可以修改定时任务时间的接口,一旦我们想要修改定时任务的时间,直接调用这个接口即可。

SchedulerController

package com.panda.scheduler.controller;
import com.panda.scheduler.scheduler.SendEmailScheduler;
import common.core.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@Slf4j
@RestController
@RequestMapping("scheduler")
public class SchedulerController {
    @Resource
    private SendEmailScheduler sendEmailScheduler;
    @GetMapping("changeCron")
    public Result<Boolean> changeCron(String cron) {
        log.info("cron = {}", cron);
        sendEmailScheduler.setSendEmailCron(cron);
        return Result.success(true);

对外暴露一个changeCron接口,用于修改定时任务的时间(如果有多个定时任务,就要有多个接口,毕竟每个定时任务的时间大概率可能不一样)。

注意这句代码:

sendEmailScheduler.setSendEmailCron(cron);

如果你一时间没有想明白setSendEmailCron从何而来,我怎么找不到这个方法呢?!看看定时任务SendEmailScheduler类上的Setter注解就能明白了。

测试

启动应用程序后,从控制台可以看出,定时任务确实是每5秒执行一次,如下所示。

"D:\Program Files (x86)\Java\jdk-11.0.17\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:58712,suspend=y,server=n -Dvisualgc.id=135029470029400 -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -javaagent:C:\Users\yangl\AppData\Local\JetBrains\IntelliJIdea2021.1\captureAgent\debugger-agent.jar=file:/C:/Users/yangl/AppData/Local/Temp/capture.props -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dfile.encoding=UTF-8 -classpath "D:\Workspace\01-java\mykits\scheduler-demo\target\classes;D:\Workspace\01-java\mykits\common\target\classes;D:\Repository\org\springframework\boot\spring-boot-starter-web\2.7.5\spring-boot-starter-web-2.7.5.jar;D:\Repository\org\springframework\boot\spring-boot-starter\2.7.5\spring-boot-starter-2.7.5.jar;D:\Repository\org\springframework\boot\spring-boot\2.7.5\spring-boot-2.7.5.jar;D:\Repository\org\springframework\boot\spring-boot-autoconfigure\2.7.5\spring-boot-autoconfigure-2.7.5.jar;D:\Repository\org\springframework\boot\spring-boot-starter-logging\2.7.5\spring-boot-starter-logging-2.7.5.jar;D:\Repository\ch\qos\logback\logback-classic\1.2.11\logback-classic-1.2.11.jar;D:\Repository\ch\qos\logback\logback-core\1.2.11\logback-core-1.2.11.jar;D:\Repository\org\apache\logging\log4j\log4j-to-slf4j\2.17.2\log4j-to-slf4j-2.17.2.jar;D:\Repository\org\apache\logging\log4j\log4j-api\2.17.2\log4j-api-2.17.2.jar;D:\Repository\org\slf4j\jul-to-slf4j\1.7.36\jul-to-slf4j-1.7.36.jar;D:\Repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\Repository\org\yaml\snakeyaml\1.30\snakeyaml-1.30.jar;D:\Repository\org\springframework\boot\spring-boot-starter-json\2.7.5\spring-boot-starter-json-2.7.5.jar;D:\Repository\com\fasterxml\jackson\core\jackson-databind\2.13.4.2\jackson-databind-2.13.4.2.jar;D:\Repository\com\fasterxml\jackson\core\jackson-annotations\2.13.4\jackson-annotations-2.13.4.jar;D:\Repository\com\fasterxml\jackson\core\jackson-core\2.13.4\jackson-core-2.13.4.jar;D:\Repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.13.4\jackson-datatype-jdk8-2.13.4.jar;D:\Repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.13.4\jackson-datatype-jsr310-2.13.4.jar;D:\Repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.13.4\jackson-module-parameter-names-2.13.4.jar;D:\Repository\org\springframework\boot\spring-boot-starter-tomcat\2.7.5\spring-boot-starter-tomcat-2.7.5.jar;D:\Repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.68\tomcat-embed-core-9.0.68.jar;D:\Repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.68\tomcat-embed-el-9.0.68.jar;D:\Repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.68\tomcat-embed-websocket-9.0.68.jar;D:\Repository\org\springframework\spring-web\5.3.23\spring-web-5.3.23.jar;D:\Repository\org\springframework\spring-beans\5.3.23\spring-beans-5.3.23.jar;D:\Repository\org\springframework\spring-webmvc\5.3.23\spring-webmvc-5.3.23.jar;D:\Repository\org\springframework\spring-aop\5.3.23\spring-aop-5.3.23.jar;D:\Repository\org\springframework\spring-context\5.3.23\spring-context-5.3.23.jar;D:\Repository\org\springframework\spring-expression\5.3.23\spring-expression-5.3.23.jar;D:\Repository\org\projectlombok\lombok\1.18.24\lombok-1.18.24.jar;D:\Repository\com\alibaba\fastjson2\fastjson2\2.0.18\fastjson2-2.0.18.jar;D:\Repository\org\slf4j\slf4j-api\1.7.36\slf4j-api-1.7.36.jar;D:\Repository\org\springframework\spring-core\5.3.23\spring-core-5.3.23.jar;D:\Repository\org\springframework\spring-jcl\5.3.23\spring-jcl-5.3.23.jar;D:\Program Files (x86)\IntelliJ IDEA 2021.1.3\lib\idea_rt.jar"




    
 com.panda.scheduler.SchedulerDemoApplication
Connected to the target VM, address: '127.0.0.1:58712', transport: 'socket'
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.7.5)
2022-12-17 17:33:29.107  INFO 21832 --- [           main] c.p.scheduler.SchedulerDemoApplication   : Starting SchedulerDemoApplication using Java 11.0.17 on yanglz with PID 21832 (D:\Workspace\01-java\mykits\scheduler-demo\target\classes started by yangl in D:\Workspace\01-java\mykits)
2022-12-17 17:33:29.113  INFO 21832 --- [           main] c.p.scheduler.SchedulerDemoApplication   : The following 1 profile is active: "dev"
2022-12-17 17:33:29.497  INFO 21832 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2022-12-17 17:33:29.502  INFO 21832 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2022-12-17 17:33:29.502  INFO 21832 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.68]
2022-12-17 17:33:29.558  INFO 21832 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2022-12-17 17:33:29.558  INFO 21832 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 426 ms
2022-12-17 17:33:29.747  INFO 21832 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2022-12-17 17:33:29.751  INFO 21832 --- [           main] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
2022-12-17 17:33:29.761  INFO 21832 --- [           main] c.p.scheduler.SchedulerDemoApplication   : Started SchedulerDemoApplication in 0.84 seconds (JVM running for 1.369)
2022-12-17 17:33:30.017  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : >>>>>>定时任务开始时间 2022-12-17 17:33:30
2022-12-17 17:33:30.019  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : 定时任务具体业务逻辑模拟业务逻辑处理......
2022-12-17 17:33:31.029  INFO 21832 --- [pool-1-thread-1]




    
 c.p.s.scheduler.SendEmailScheduler       : >>>>>>定时任务结束时间 2022-12-17 17:33:31
2022-12-17 17:33:35.014  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : >>>>>>定时任务开始时间 2022-12-17 17:33:35
2022-12-17 17:33:35.014  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : 定时任务具体业务逻辑模拟业务逻辑处理......
2022-12-17 17:33:36.026  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : >>>>>>定时任务结束时间 2022-12-17 17:33:36
2022-12-17 17:33:40.008  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : >>>>>>定时任务开始时间 2022-12-17 17:33:40
2022-12-17 17:33:40.008  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : 定时任务具体业务逻辑模拟业务逻辑处理......
2022-12-17 17:33:41.009  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : >>>>>>定时任务结束时间 2022-12-17 17:33:41
2022-12-17 17:33:46.026  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : >>>>>>定时任务结束时间 2022-12-17 17:33:46

然后我们调用修改定时任务的接口/scheduler/changeCron,参数为0/5 * * * * ?(即定时任务每隔15秒执行一次)。

从控制台可以看出,定时任务的执行时间由每5秒执行一次变为每15秒执行一次,如下所示。

2022-12-17 17:33:42.067  INFO 21832 --- [nio-8080-exec-1] c.p.s.controller.SchedulerController     : cron = 0/15 * * * * ?
2022-12-17 17:34:00.003  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : >>>>>>定时任务开始时间 2022-12-17 17:34:00
2022-12-17 17:34:00.003  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : 定时任务具体业务逻辑模拟业务逻辑处理......
2022-12-17 17:34:01.014  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : >>>>>>定时任务结束时间 2022-12-17 17:34:01
2022-12-17 17:34:15.005  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : >>>>>>定时任务开始时间 2022-12-17 17:34:15
2022-12-17 17:34:15.005  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : 定时任务具体业务逻辑模拟业务逻辑处理......
2022-12-17 17:34:16.015  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : >>>>>>定时任务结束时间 2022-12-17 17:34:16
2022-12-17 17:34:30.012  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : >>>>>>定时任务开始时间 2022-12-17 17:34:30
2022-12-17




    
 17:34:30.012  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : 定时任务具体业务逻辑模拟业务逻辑处理......
2022-12-17 17:34:31.024  INFO 21832 --- [pool-1-thread-1] c.p.s.scheduler.SendEmailScheduler       : >>>>>>定时任务结束时间 2022-12-17 17:34:31

分析

当我们配置定时任务的执行时间为 0/5 * * * * ? ,定时任务确实是每隔5秒执行一次:

第一次执行时间:2022-12-17 17:33: 30 .017。

第二次执行时间:2022-12-17 17:33: 35 .014 。

第三次执行时间:2022-12-17 17:33: 40 .008 。

第四次执行时间:2022-12-17 17:33: 45 .011。

当我们动态修改定时任务的时间为 0/15 * * * * ? ,定时任务确实是每隔15秒执行一次:

第一次执行时间:2022-12-17 17:34: 00 .003 。

第二次执行时间: 2022-12-17 17:34: 15 .005。

第三次执行时间: 2022-12-17 17:34: 30 .012。

从以上分析可以看出,当我们通过接口动态修改定时任务的时间时,定时任务确实会按照我们修改后的时间间隔执行定时任务,也就是说通过接口动态修改定时任务的时间是可行的。

除了上面介绍的借助cron表达式的CronTrigger触发器,还有另一种触发器PeriodicTrigger。

两者的区别在于,CronTrigger触发器通过cron表达式只能定义小于等于间隔59秒(但是不能设置间隔100秒,1000秒等时间间隔,但是可以设置每个1分钟、1小时,每天的11,12,13点等)。

而PeriodicTrigger触发器可随意设置循环间隔时间,例如,间隔1000秒,10000秒等。

下面我们来测试一下这个触发器的用法,并验证一下是否真的可以随意设置循环间隔时间。

PeriodicTrigger触发器简介

PeriodicTrigger是周期性定期任务执行的触发器。

该周期可以被应用为固定速率或固定延迟,并且还可以配置初始延迟值。

所谓固定速率是指从任务的开始时间算起,每个指定时间执行,即使上一个任务没有执行完毕,一旦到了时间间隔,也会执行下一个任务。

所谓固定延迟是指在上一个任务执行完毕之后,间隔指定的时间,开始执行下一个任务。

PeriodicTrigger的默认初始延迟为0,默认行为为固定延迟 (即从每个完成时间开始测量连续执行之间的间隔)。

如果我们想要按照固定速率的模式执行定时任务,需要将将“fixedRate”属性设置为true

代码示例二:PeriodicTrigger触发器

application.yml配置文件

server:
  port: 8080
  servlet:
    context-path: /
scheduler:
  # 发送邮件定时任务的时间每5秒执行一次
  sendEmailCron: 0/5 * * * * ?
  # 删除无效数据定时任务的时间单位毫秒
  deleteInvalidData: 10000

在配置文件中添加删除无效数据的定时任务的时间:deleteInvalidData:10000。

SchedulerDemoApplication

同上,不再赘述。

DeleteInvalidDataScheduler

package com.panda.scheduler.scheduler;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Component
@Slf4j
@Getter
@Setter
public class DeleteInvalidDataScheduler implements SchedulingConfigurer {
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    @Value("${scheduler.deleteInvalidData}")
    private long deleteInvalidData;
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        // 使用cron表达式可以动态地设置循环间隔
        taskRegistrar.addTriggerTask(() -> {
            log.info(">>>>>>定时任务开始时间: {}", LocalDateTime.now().format(DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS)));
            // 定时任务具体业务逻辑,模拟业务逻辑处理
            log.info(">>>>>>定时任务结束时间: {}", LocalDateTime.now().format(DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS)));
        }, triggerContext -> {
            // 使用PeriodicTrigger触发器,可随意设置循环间隔时间
            PeriodicTrigger periodicTrigger = new PeriodicTrigger(deleteInvalidData);
            return periodicTrigger.nextExecutionTime(triggerContext);

和上个例子不同的是,我们通过PeriodicTrigger触发器设置定时任务执行的频率。

SchedulerController

package com.panda.scheduler.controller;
import com.panda.scheduler.scheduler.DeleteInvalidDataScheduler;
import com.panda.scheduler.scheduler.SendEmailScheduler;
import common.core.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@Slf4j
@RestController
@RequestMapping("scheduler")
public class SchedulerController {
    @Resource
    private SendEmailScheduler sendEmailScheduler;
    @Resource
    private DeleteInvalidDataScheduler deleteInvalidDataScheduler;
    @GetMapping("changeCron")
    public Result<Boolean> changeCron(String cron) {
        log.info("cron = {}", cron);
        sendEmailScheduler.setSendEmailCron(cron);
        return Result.success(true);
    @GetMapping("changeDeleteInvalidDataCron")
    public Result<Boolean> changeDeleteInvalidDataCron(long period) {
        log.info("period = {} ms", period);
        deleteInvalidDataScheduler.setDeleteInvalidData(period);
        return Result.success(true);

新增changeDeleteInvalidDataCron接口,用于动态修改删除无效数据的定时任务的时间。

测试

启动应用程序后,从控制台可以看出,定时任务确实是每10秒执行一次,如下所示。

2022-12-17 18:14:38.459  INFO 26248 --- [pool-1-thread-1] c.p.s.s.DeleteInvalidDataScheduler       : 
>>>>>>定时任务开始时间 2022-12-17 18:14:38
2022-12-17 18:14:38.460  INFO 26248 --- [pool-1-thread-1] c.p.s.s.DeleteInvalidDataScheduler       : 
>>>>>>定时任务结束时间 2022-12-17 18:14:38
2022-12-17 18:14:48.466  INFO 26248 --- [pool-1-thread-1] c.p.s.s.DeleteInvalidDataScheduler       : 
>>>>>>定时任务开始时间 2022-12-17 18:14:48
2022-12-17 18:14:48.467  INFO 26248 --- [pool-1-thread-1] c.p.s.s.DeleteInvalidDataScheduler       : 
>>>>>>定时任务结束时间 2022-12-17 18:14:48
2022-12-17 18:14:58.476  INFO 26248 --- [pool-1-thread-1] c.p.s.s.DeleteInvalidDataScheduler       : 
>>>>>>定时任务开始时间 2022-12-17 18:14:58
2022-12-17 18:14:58.476  INFO 26248 --- [pool-1-thread-1] c.p.s.s.DeleteInvalidDataScheduler       : 
>>>>>>定时任务结束时间 2022-12-17 18:14:58
2022-12-17 18:15:08.488  INFO 26248 --- [pool-1-thread-1] c.p.s.s.DeleteInvalidDataScheduler       : 
>>>>>>定时任务开始时间 2022-12-17 18:15:08
2022-12-17 18:15:08.488  INFO 26248 --- [pool-1-thread-1] c.p.s.s.DeleteInvalidDataScheduler       : 
>>>>>>定时任务结束时间 2022-12-17 18:15:08

然后我们调用修改定时任务的接口/scheduler/changeDeleteInvalidDataCron,参数为15000(即定时任务每隔15秒执行一次)。

从控制台可以看出,定时任务的执行时间由每10秒执行一次变为每15秒执行一次,如下所示。

2022-12-17 18:15:01.162  INFO 26248 --- [nio-8080-exec-1] c.p.s.controller.SchedulerController     : period = 15000 ms
2022-12-17 18:15:23.499  INFO 26248 --- [pool-1-thread-1] c.p.s.s.DeleteInvalidDataScheduler       : 
>>>>>>定时任务开始时间 2022-12-17 18:15:23
2022-12-17 18:15:23.499  INFO 26248 --- [pool-1-thread-1] c.p.s.s.DeleteInvalidDataScheduler       : 
>>>>>>定时任务结束时间 2022-12-17 18:15:23
2022-12-17 18:15:38.513  INFO 26248 --- [pool-1-thread-1] c.p.s.s.DeleteInvalidDataScheduler       : 
>>>>>>定时任务开始时间 2022-12-17 18:15:38