SpringBoot 设置动态定时任务,千万别再写死了~

news2024/9/25 1:15:19

怎么在SpringBoot项目中简单使用定时任务,不过由于要借助cron表达式且都提前定义好放在配置文件里,不能在项目运行中动态修改任务执行时间,实在不太灵活。

经过网上搜索学习后,特此记录如何在SpringBoot项目中实现动态定时任务。

因为只是一个demo,所以只引入了需要的依赖:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
            <optional>true</optional>
        </dependency>
 
        <!-- spring boot 2.3版本后,如果需要使用校验,需手动导入validation包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

启动类:

package com.wl.demo;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
 
@EnableScheduling
@SpringBootApplication
public class DemoApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
        System.out.println("(*^▽^*)启动成功!!!(〃'▽'〃)");
    }
}

配置文件application.yml,只定义了服务端口:

server:
  port: 8089

定时任务执行时间配置文件:task-config.ini:

printTime.cron=0/10 * * * * ?

定时任务执行类:

package com.wl.demo.task;
 
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
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.util.Date;
 
@Data
@Slf4j
@Component
@PropertySource("classpath:/task-config.ini")
public class ScheduleTask implements SchedulingConfigurer {
 
    @Value("${printTime.cron}")
    private String cron;
 
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        // 动态使用cron表达式设置循环间隔
        taskRegistrar.addTriggerTask(new Runnable() {
            @Override
            public void run() {
                log.info("Current time: {}", LocalDateTime.now());
            }
        }, new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                // 使用CronTrigger触发器,可动态修改cron表达式来操作循环规则
                CronTrigger cronTrigger = new CronTrigger(cron);
                Date nextExecutionTime = cronTrigger.nextExecutionTime(triggerContext);
                return nextExecutionTime;
            }
        });
    }
}

编写一个接口,使得可以通过调用接口动态修改该定时任务的执行时间:

package com.wl.demo.controller;
 
import com.wl.demo.task.ScheduleTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
 
    private final ScheduleTask scheduleTask;
 
    @Autowired
    public TestController(ScheduleTask scheduleTask) {
        this.scheduleTask = scheduleTask;
    }
 
    @GetMapping("/updateCron")
    public String updateCron(String cron) {
        log.info("new cron :{}", cron);
        scheduleTask.setCron(cron);
        return "ok";
    }
}

启动项目,可以看到任务每10秒执行一次:

图片

访问接口,传入请求参数cron表达式,将定时任务修改为15秒执行一次:

图片

可以看到任务变成了15秒执行一次
在这里插入图片描述

除了上面的借助cron表达式的方法,还有另一种触发器,区别于CronTrigger触发器,该触发器可随意设置循环间隔时间,不像cron表达式只能定义小于等于间隔59秒。

package com.wl.demo.task;
 
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.stereotype.Component;
 
import java.time.LocalDateTime;
import java.util.Date;
 
@Data
@Slf4j
@Component
@PropertySource("classpath:/task-config.ini")
public class ScheduleTask implements SchedulingConfigurer {
 
    @Value("${printTime.cron}")
    private String cron;
 
    private Long timer = 10000L;
 
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        // 动态使用cron表达式设置循环间隔
        taskRegistrar.addTriggerTask(new Runnable() {
            @Override
            public void run() {
                log.info("Current time: {}", LocalDateTime.now());
            }
        }, new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                // 使用CronTrigger触发器,可动态修改cron表达式来操作循环规则
//                CronTrigger cronTrigger = new CronTrigger(cron);
//                Date nextExecutionTime = cronTrigger.nextExecutionTime(triggerContext);
 
                // 使用不同的触发器,为设置循环时间的关键,区别于CronTrigger触发器,该触发器可随意设置循环间隔时间,单位为毫秒
                PeriodicTrigger periodicTrigger = new PeriodicTrigger(timer);
                Date nextExecutionTime = periodicTrigger.nextExecutionTime(triggerContext);
                return nextExecutionTime;
            }
        });
    }
}

增加一个修改时间的接口:

package com.wl.demo.controller;
 
import com.wl.demo.task.ScheduleTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
 
    private final ScheduleTask scheduleTask;
 
    @Autowired
    public TestController(ScheduleTask scheduleTask) {
        this.scheduleTask = scheduleTask;
    }
 
    @GetMapping("/updateCron")
    public String updateCron(String cron) {
        log.info("new cron :{}", cron);
        scheduleTask.setCron(cron);
        return "ok";
    }
 
    @GetMapping("/updateTimer")
    public String updateTimer(Long timer) {
        log.info("new timer :{}", timer);
        scheduleTask.setTimer(timer);
        return "ok";
    }
}

测试结果:

在这里插入图片描述

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

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

相关文章

MySQL查询序号带小数点问题

案例&#xff1a; SELECT (num:num1) AS index, name, age FROM sys_user, (SELECT num:0) AS a order by age,name; 查询结果&#xff1a; datagrip和dbeaver查询结果不一样&#xff0c;使用cmd查询&#xff0c;默认也是无小数点的 但实际返回结果&#xff0c;其实是带点的 D…

CocosCreator制作地图外物品位置向导(指引/地图标点)

演示 图解 code goldTips&#xff1a;指引节点&#xff0c;更改位置使用 goldTipRotate&#xff1a;指引节点的子节点中具有指向性的节点&#xff0c;一般为带箭头&#xff0c;尖角等。 protected lateUpdate(dt: number): void {//可以不在lateUpdate中操作&#xff0c;…

【020】C++的动态内存申请new和delete

C的动态内存申请new和delete 引言一、动态分配内存的概述二、静态分配和动态分配三、new和delete3.1、new和delete操作基本类型空间3.2、new和delete操作数组空间 四、new和delete的重载五、动态分配内存的优缺点总结 引言 &#x1f4a1; 作者简介&#xff1a;专注于C/C高性能程…

【算法系列 | 2】深入解析排序算法之插入排序

序言 你只管努力&#xff0c;其他交给时间&#xff0c;时间会证明一切。 文章标记颜色说明&#xff1a; 黄色&#xff1a;重要标题红色&#xff1a;用来标记结论绿色&#xff1a;用来标记一级论点蓝色&#xff1a;用来标记二级论点 决定开一个算法专栏&#xff0c;希望能帮助大…

看这篇文章能让你健康多活若干年

这个世界值得你多活几十年&#xff0c;即便你对现在的生活不满意&#xff0c;你也会对几十年后的生活倾慕不已。 毕竟&#xff1a; 到2029年&#xff0c;区块链就出来第二十年了&#xff0c;Web3会让我们生活得更容易。 到2042年&#xff0c;chatGPT就出来第二十年了&#xff0…

SpringCloudAlibaba

Spring Cloud Alibaba 是 Spring Cloud 的一个子项目&#xff0c;它是由阿里巴巴开发的一套微服务解决方案&#xff0c;旨在为微服务架构提供一站式解决方案&#xff0c;包括服务注册与发现、配置中心、消息总线、负载均衡、熔断器、限流器、分布式事务等组件。 Spring Cloud A…

阿里、字节大佬共创的Netty核心原理手册,必须是全网No.1

讲到这里&#xff0c;你可能要问了&#xff1a;如果我的工作中涉及网络编程的内容并不多&#xff0c;那我是否还有必要花精力学习 Netty 呢&#xff1f;其实在互联网大厂&#xff08;阿里、腾讯、美团等&#xff09;的中高级 Java 开发面试中&#xff0c;经常会问到涉及到 Nett…

将一个数组分为多个数组按其元素总数尽量均分的numpy.array_split()方法

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将一个数组s分为多个数组 按s中元素总数尽量均分 numpy.array_split() [太阳]选择题 关于以下代码说法错误的一项是? import numpy as np a np.array([1,2,3,4]) print("【显示】a &quo…

突发!ChatGPT之父警告AI可能灭绝人类,350名AI权威签署联名公开信

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ni7WOmZz-1685770686028)(C:\Users\lenovo\AppData\Local\Temp\ksohtml3116\wps1.jpg)] 就在刚刚&#xff0c;AI 领域传出一封重要的公开信。 包括 「ChatGPT 之父」Sam Altman 在内 350 位 AI 权威都…

【历史上的今天】6 月 5 日:揭幕计算机历史的一次聚会;公钥密码学先驱诞生;函数语言设计先驱出生

整理 | 王启隆 透过「历史上的今天」&#xff0c;从过去看未来&#xff0c;从现在亦可以改变未来。 今天是 2023 年 6 月 5 日&#xff0c;世界环境日。1972 年 6 月 5 日至 16 日&#xff0c;联合国人类环境会议在斯德哥尔摩举行&#xff0c;会上发表了《人类环境言》&#x…

tdesign的白天黑夜模式实现原理

以tdesign为例 我们看下源码 可以看到,tdesign是借助于:root选择器,并结合属性选择器来设置的,当html标签存在一个名叫theme-mode属性的时候,如果值为dark就使用白天的主题,否则就使用黑天的主题 我们切换下颜色,更改html当中的属性,可以看到下图的区别 <!DOCTYPE html&g…

​细说websocket -Node篇​

一、WebSocket 协议 1. 概述 websocket协议允许不受信用的客户端代码在可控的网络环境中控制远程主机。该协议包含一个握手和一个基本消息分帧、分层通过TCP。简单点说&#xff0c;通过握手应答之后&#xff0c;建立安全的信息管道&#xff0c;这种方式明显优于前文所说的基于…

中国汽车品牌出海简直“泰裤辣”!

世界上有五种辣&#xff1a;微辣、中辣、特辣、变态辣&#xff0c;还有一种叫“泰裤辣”&#xff01;随着中国汽车品牌出海的步伐加快&#xff0c;泰国市场成为了一个备受关注的目标。无论是泰国对汽车产业的激励政策&#xff0c;还是泰国当地对促进汽车消费的力度&#xff0c;…

三星不愿成为炮灰,加速抢占美光的市场,美国的愿望落空

在美光被中国实施安全审查后&#xff0c;美国曾要求韩国芯片不要趁机扩大销售&#xff0c;抢占美光留下的市场人&#xff0c;然而由于全球芯片行业的衰退&#xff0c;三星等韩国企业担忧成为炮灰而加速抢占美光的市场。 一、韩国芯片不好过 三星等韩国芯片企业如此做&#xff0…

yolov5s融合ECA、CA、Transformer等组件开发构建海洋场景下远红外目标检测模型,并进行实验对比分析

海洋海面远红外场景下的目标检测在我之前的文章中已经有过相关的实践了&#xff0c;感兴趣的话可以自行移步阅读即可。 《红外海洋目标检测实践&#xff0c;基于目标检测模型识别红外海洋目标》 《基于YOLO开发构建红外场景下无人机航拍车辆实例分割检测识别分析系统》 《红…

CAD软件外包开发的技术难点

CAD软件的开发具有一定的复杂性和挑战性&#xff0c;需要复杂的数学和几何计算&#xff0c;同时需要兼顾高性能&#xff0c;这对软件开发者有比较高的要求。今天和大家分享这方面的知识&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发…

Centos升级docker后启动容器报错“unknown or invalid runtime name”

前言 操作系统为centosdocker原来的版本为1.31.1&#xff0c;升级后为20结尾有升级docker的教程听说图片能凑字数&#xff0c;就截图贴了 插播一个问题记录 加入后面出现无法强制删除镜像文件时&#xff0c;或者报错&#xff08;无法创建容器&#xff09; 按照如下解决 1. 报…

多语言跨境商城源码系统选择定制开发|多语言电商源码

多语言跨境商城源码选择 欢迎名片沟通 多语言跨境商城源码系统应当具有符合自身需求的语言和环境&#xff0c;具体应有&#xff1a;多语言支持、界面设计、支付方式、物流配送、安全性、性能和稳定性、可扩展性等等。具体如下&#xff1a; 多语言支持——具备语言切换…

13.生命周期函数

小程序中的生命周期函数分为两种 应用生命周期函数&#xff1a;整个应用的生命周期函数页面生命后期函数 目录 1 应用生命周期函数 1.1 初始化时 onLanch 1.2 隐藏小程序时 onHide 1.3 显示小程序时 onShow 2 页面生命周期函数 2.1 初始化时 onLoad 2.2 页面显…

C语言写网络爬虫总体思路

使用C语言编写爬虫可以实现网络数据的快速获取和处理&#xff0c;适用于需要高效处理海量数据的场景。与其他编程语言相比&#xff0c;C语言具有较高的性能和灵活性&#xff0c;可以进行底层操作和内存管理&#xff0c;适合处理较复杂的网络请求和数据处理任务。 但是&#xf…