Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SpringBoot 设置动态定时任务,千万别再写死了~

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

作者头像
Java团长
发布于 2022-12-20 11:03:00
发布于 2022-12-20 11:03:00
2.3K00
代码可运行
举报
运行总次数:0
代码可运行

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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>

启动类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.wl.demo;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
 
/**
 * @author wl
 * @date 2022/3/22
 */
@EnableScheduling
@SpringBootApplication
public class DemoApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
        System.out.println("(*^▽^*)启动成功!!!(〃'▽'〃)");
    }
}

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
server:
  port: 8089

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
printTime.cron=0/10 * * * * ?

定时任务执行类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
 
/**
 * 定时任务
 * @author wl
 * @date 2022/3/22
 */
@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;
            }
        });
    }
}

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
 
/**
 * @author wl
 * @date 2022/3/22
 */
@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秒。需要开通正版IDEA的可以加我微信:poxiaozhiai6,56元一年。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
 
/**
 * 定时任务
 * @author wl
 * @date 2022/3/22
 */
@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;
            }
        });
    }
}

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
 
/**
 * @author wl
 * @date 2022/3/22
 */
@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";
    }
}

测试结果:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-09-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java团长 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
SpringBoot系列之动态定时程序改进版
基于上篇博客,做了一版动态定时程序,然后发现这个定时程序需要在下次执行的时候会加载新的时间,所以如果改了定时程序不能马上触发,所以想到一种方法,在保存定时程序的时候将cron表达式传过去,然后触发定时程序,下面看看怎么实现
SmileNicky
2022/11/18
4720
SpringBoot 实现固定、动态定时任务 | 三种实现方式 | 附源代码
背景:📅 最近要用到这个定时任务,之前就简单使用注解的那种方式,需求一变化,就得重新修改。 就想到了动态定时任务,连接数据库来动态选择,这样确实解决了问题。 但是仍然有一个缺陷,就是没法设置任务的执行时间,无法做到像 QQ 发说说那样,给 xdm 祝福生日时,设定说说为晚上00:00发布。 本文就以上三点用自己的思路写了一个小Demo,希望对大家有所帮助。 👩‍💻 封面:来自于校园一角,秋意渐浓,思念渐深。 前言: 阅读完本文:🐱‍👓 知晓 SpringBoot 用注解如何实现定时任务 明白
宁在春
2022/10/31
7.6K0
SpringBoot 实现固定、动态定时任务 | 三种实现方式 | 附源代码
SpringBoot+MySQL实现动态定时任务
一个极简的基于springboot的动态定时任务demo,spring-context模块有对任务调度进行支持,本demo也是基于这个模块进行开发,功能相对简单,用户可以按需改造,比如添加运维界面,在界面上更加灵活的控制任务执行与更新。
科技新语
2025/05/09
1310
SpringBoot+MySQL实现动态定时任务
Spring 实现 SchedulingConfigurer 接口完成动态定时任务(配合数据库动态执行)
Spring 实现 SchedulingConfigurer 接口完成动态定时任务(配合数据库动态执行)
一个会写诗的程序员
2018/08/17
5.1K0
​基于SpringBoot的轻量、非侵入数据库数据告警工具
「 傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。--------王小波」
山河已无恙
2023/01/30
6100
SpringBoot基于数据库的定时任务实现
在我们平时开发的项目中,定时任务基本属于必不可少的功能,那大家都是怎么做的呢?但我知道的大多都是静态定时任务实现。
攻城狮的那点事
2019/12/27
1.5K0
SpringBoot基于数据库的定时任务实现
SpringBoot实现定时任务的三种方式,总有一款适合你!
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/03/30
5.5K0
ShedLock的4种使用方式(分布式定时任务锁)
基于注解@Scheduled默认为单线程,开启多个任务时,任务的执行时机会受上一个任务执行时间的影响,上一个线程不执行完成,下一个不会执行。
ha_lydms
2023/08/10
2.4K0
ShedLock的4种使用方式(分布式定时任务锁)
在Spring Boot中优雅的实现定时任务
在日常的项目开发中,往往会涉及到一些需要做到定时执行的代码,例如自动将超过24小时的未付款的单改为取消状态,自动将超过14天客户未签收的订单改为已签收状态等等,那么为了在Spring Boot中实现此类需求,我们要怎么做呢?
用户2781897
2020/11/02
1.2K0
在Spring Boot中优雅的实现定时任务
SpringBoot系列之动态生成cron表达式执行定时程序
最近需要实现一个功能,根据页面选择的星期,默认是凌晨执行,生成cron表达式,然后定时执行定时程序
SmileNicky
2022/11/06
2.8K0
SpringBoot系列之动态生成cron表达式执行定时程序
Spring 中,定时任务接口 SchedulingConfigurer
Spring 中,创建定时任务除了使用@Scheduled 注解外,还可以使用 SchedulingConfigurer。
水货程序员
2018/11/13
24.5K2
SpringBoot——动态多线程并发定时任务
怎么重新调用 refreshTask()方法:可以另外启一个任务实时监控任务表的数据变化。
默存
2022/06/24
3960
SpringBoot——动态多线程并发定时任务
基于Spring Task的Spring定时任务
基于注解形式的一般都是静态的定时任务,就是注解中的内容是固定的并且只有一个定时任务,而实现接口的可以是动态的,可以根据配置文件和数据库进行切换。
闫同学
2022/10/31
6220
基于Spring Task的Spring定时任务
SpringBoot 动态修改定时任务频率
调试情况如下: 1.调用start 2.调用change,并传入0/3 * * * * * 3.调用stop
软件测试君
2020/05/13
1.2K0
Java之定时任务全家桶
由此看出走不同的线程执行,不同的线程执行的好处是,如果某一个线程挂掉后,并不会阻塞导致其它定时任务无法执行。
BUG弄潮儿
2021/03/04
6050
springboot scheduled并发配置
本文介绍如何使用springboot的sheduled实现任务的定时调度,并将调度的任务实现为并发的方式。 1、定时调度配置scheduled 1)注册定时任务 package com.xiaoju.dqa.sentinel.scheduler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.spr
用户1225216
2018/03/05
3.8K0
Spring Boot: 定时任务注解@Scheduled以及动态任务SchedulingConfigurer 实践
cronExpression定义时间规则,Cron表达式由6或7个空格分隔的时间字段组成:秒 分钟 小时 日期 月份 星期 年(可选)
Freedom123
2024/03/29
2.7K0
Spring Boot: 定时任务注解@Scheduled以及动态任务SchedulingConfigurer 实践
SpringBoot动态配置定时任务cron(动态改变执行周期)
package model; public class SpringScheduledCron { private String cronId; private String cronKey; private String cronExpression; private String taskExplain; private String status; @Override public String toString() {
JQ实验室
2022/02/10
1.7K0
Spring Boot 2.X(十二):定时任务
定时任务是后端开发中常见的需求,主要应用场景有定期数据报表、定时消息通知、异步的后台业务逻辑处理、日志分析处理、垃圾数据清理、定时更新缓存等等。
朝雾轻寒
2019/11/05
6340
Spring Boot 2.X(十二):定时任务
玩转 Spring Boot 集成篇(@Scheduled、静态、动态定时任务)(七)
研发说:API 请求量到底啥情况呀?统计发粗来(万一访问量一直激增,导致服务宕了,要扣我绩效滴)。
botkenni
2022/09/23
1.2K0
玩转 Spring Boot 集成篇(@Scheduled、静态、动态定时任务)(七)
推荐阅读
相关推荐
SpringBoot系列之动态定时程序改进版
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验