通过SchedulingConfigurer 接口完成动态定时任务

通过SchedulingConfigurer 接口完成动态定时任务

一.背景

在Spring中,除了使用@Scheduled注解外,还可以通过实现SchedulingConfigurer接口来创建定时任务。它们之间的主要区别在于灵活性和动态性。@Scheduled注解适用于固定周期的任务,一旦任务的执行时间设定,就无法在运行时动态更改,因此如果需要调整任务执行周期,通常需要停止服务、修改配置,然后重启服务。相比之下,通过实现SchedulingConfigurer接口来配置定时任务可以实现更大的灵活性,可以在运行时动态调整任务的执行时间或周期,而无需停止和重启服务。这种方式特别适合需要根据外部条件或运行时数据动态调整任务调度的场景。

二.实现

2.1.创建数据表

我们创建了一个名为scheduled的数据库表,用于存储定时任务的配置信息,并向该表中插入了一条具体的定时任务配置记录。

CREATE TABLE `scheduled` (`id` INT,`task_key` VARCHAR ( 127 ) COMMENT '任务key值',`name` VARCHAR ( 127 ) COMMENT '任务名称',`cron` VARCHAR ( 63 ) COMMENT '任务表达式',`status` INT DEFAULT 0 COMMENT '状态(1.禁用; 0.启用)',
PRIMARY KEY ( `id` ) 
) COMMENT = '定时任务配置表';INSERT INTO `scheduled` (`id`, `task_key`, `name`, `cron`, `status`) VALUES (1, 'myTask', '我的定时任务', '0 0/5 * * * ?', 0);

2.2.创建实体类

这段代码使用了JPA(Java Persistence API)注解,定义了一个与数据库表 scheduled 对应的Java实体类 Scheduled。它包含了与定时任务相关的基本属性字段,并通过注解将这些字段映射到数据库表的对应列上。同时,使用Lombok的 @Data 注解简化了实体类的getter、setter等方法的编写。

package com.temperature.humidity.system.entity;import lombok.Data;import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;@Table(name = "scheduled")
@Data
@Entity
public class Scheduled {@Id@Column(name = "id")private Integer id;@Column(name = "task_key")private String taskKey;@Column(name = "name")private String name;@Column(name = "cron")private String cron;@Column(name = "status")private Integer status;}

2.3.Dao层接口

通过 taskKey 和 status 属性来查找 Scheduled 实体对象。

package com.temperature.humidity.system.repository.jpa;import com.temperature.humidity.system.entity.Scheduled;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;@Repository
public interface ScheduledRepository extends JpaRepository<Scheduled, Integer> {//通过taskKey和status查找ScheduledScheduled findFirstByTaskKeyAndStatus(String taskKey, Integer status);
}

2.4.定时任务父类

BaseScheduleTask 抽象类提供了一个通用的定时任务结构,使得子类只需实现具体的任务逻辑和 cron 表达式的获取逻辑即可。它利用了 Spring 的定时任务配置支持,通过依赖注入和抽象方法的方式,实现了定时任务的灵活配置和执行。

package com.temperature.humidity.system.schedule;import com.temperature.humidity.system.entity.Scheduled;
import com.temperature.humidity.system.repository.jpa.ScheduledRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;/*** 定时任务父类*/
@Slf4j
public abstract class BaseScheduleTask implements SchedulingConfigurer {private static final String LOG_HEADER = "[定时任务父类]";@Autowiredprivate ScheduledRepository scheduledRepository;@Autowiredprivate TaskScheduler threadPoolTaskScheduler;@Overridepublic void configureTasks(ScheduledTaskRegistrar taskRegistrar) {taskRegistrar.setTaskScheduler(threadPoolTaskScheduler);taskRegistrar.addTriggerTask(//1.添加任务内容(Runnable)this::execTask,//2.设置执行周期(Trigger)triggerContext -> new CronTrigger(this.childGetCron()).nextExecutionTime(triggerContext));}public void execTask() {this.childExec();}/*** 子类实际的工作内容*/public abstract void childExec();/*** 子类获得执行的cron表达式** @return*/public abstract String childGetCron();public abstract String getName();/*** 获取任务执行的Cron表达式*/protected String getTimeCron(String paraSortCode, String name, String defaultValue) {String cron = defaultValue;Scheduled scheduled = scheduledRepository.findFirstByTaskKeyAndStatus(paraSortCode, 0);if (scheduled != null) {cron = scheduled.getCron();}log.info("{},当前任务【{}-{}】,获得的cron表达式:{}", LOG_HEADER, paraSortCode, name, cron);return cron;}
}

2.5.定时任务子类

这里我们举了一个例子,通过继承BaseScheduleTask 并重写其的一些方法来达到动态配置定时任务的目的。

  • childExec:实际的工作内容
  • childGetCron:获得执行的cron表达式。
  • getName:为了控制台打印出一个方便记忆的定时任务名字。
package com.temperature.humidity.system.schedule.task;import com.temperature.humidity.system.schedule.BaseScheduleTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import java.util.Date;@Slf4j
@Component
public class MyTask extends BaseScheduleTask {@Overridepublic void childExec() {log.info("我被执行了当前时间为{}", new Date());}@Overridepublic String childGetCron() {return getTimeCron("myTask", getName(), "0 0/15 * * * ?");}@Overridepublic String getName() {return "我的定时任务";}
}

三.效果

效果如下所示,可以看到实际执行的任务按照数据库配置的corn表达式执行,而不是之前设置的默认的执行。
在这里插入图片描述

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

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

相关文章

生成式 AI 的未来,对话系统 (Chat)与自主代理 (Agent)相辅相成

目录 1. 概念解释生成式 AI对话系统 (Chat)自主代理 (Agent) 2. 代码示例对话系统示例 (使用 Python 和 NLTK 库)自主代理示例 (使用 Python 模拟简单的自主学习) 3. 逻辑性分析4. 通俗易懂的解释5. 与其他相似概念的对比6. 常见问题和解答7. 技术挑战与解决方案对话系统的技术…

内容安全(深度行为检测技术、IPS、AV、入侵检测方法)

1、深度行为检测技术 深度行为检测技术&#xff1a;是一种基于深度学习和机器学习的技术&#xff0c;它通过分析用户在网络中的行为模式&#xff0c;识别异常或潜在威胁行为&#xff0c;从而保护网络安全和内容安全 分类&#xff1a; 深度包检测技术&#xff08;Deep Packet…

Kafka Producer发送消息流程之消息异步发送和同步发送

文章目录 1. 异步发送2. 同步发送 1. 异步发送 Kafka默认就是异步发送&#xff0c;在Main线程中的多条消息&#xff0c;没有严格的先后顺序&#xff0c;Sender发送后就继续下一条&#xff0c;异步接受结果。 public class KafkaProducerCallbackTest {public static void mai…

Unity Apple Vision Pro 开发(四):体积相机 Volume Camera

文章目录 &#x1f4d5;教程说明&#x1f4d5;教程内容概括&#x1f4d5;体积相机作用&#x1f4d5;创建体积相机&#x1f4d5;添加体积相机配置文件&#x1f4d5;体积相机配置文件参数&#x1f4d5;体积相机的边界盒大小&#x1f4d5;体积相机边界盒大小和应用边界盒大小的区别…

【GraphRAG】微软 graphrag 效果实测

GraphRAG 本文将基于以下来源&#xff0c;对Microsoft GraphRAG分析优缺点、以及示例实测分析。 1. Source 代码仓库&#xff1a; Welcome to GraphRAGhttps://microsoft.github.io/graphrag/ 微软文章1&#xff08;2024.2.13&#xff09;&#xff1a;GraphRAG: Unlocking…

Hadoop3:MR程序的数据倾斜问题处理

一、数据倾斜 什么是数据倾斜&#xff1f; 学过Redis集群的都知道数据倾斜这个问题。 就是大量数据&#xff0c;分配不均匀的现象。 二、MR数据倾斜 1、怎么判断出现数据倾斜&#xff1f; 数据频率倾斜——某一个区域的数据量要远远大于其他区域。 数据大小倾斜——部分记…

Android中OkHttp3中超时时间概述

目录 前言connectTimeoutreadTimeoutwriteTimeoutcallTimeoutpingInterval拓展 前言 可以看到&#xff0c;使用还是很简单的。主要相关的有这五个参数&#xff0c;其中我们常用到是就是connectTimeout、readTimeout和writeTimeout。 再看上图&#xff0c;可以看到默认下connec…

js | Core

http://dmitrysoshnikov.com/ecmascript/javascript-the-core/ Object 是什么&#xff1f; 属性[[prototype]]对象。 例如&#xff0c;下面的&#xff0c;son是对象&#xff0c;foo不是对象。打印出来的son&#xff0c;能看到有一个prototype 对象。 prototype vs _proto_ v…

R语言实现神经网络ANN

# 常用激活函数 # 自定义Sigmoid函数 sigmod <- function(x){return(1/(1exp(-x))) } # 绘制Sigmoid曲线 x <- seq(-10,10,length.out 100) plot(x,sigmod(x),type l,col blue,lwd 2,xlab NA,ylab NA,main Sigmoid函数曲线)# 自定义Tanh函数 tanh <- function(…

Qt QProcess 进程间通信读写数据通信

本文介绍了如何使用Qt的QProcess 进行程序开发&#xff0c;包括启动进程间通信、设置环境变量、通用方法&#xff1b;方便在日常开发中使用&#xff1b; 1.使用Qt进行程序开发&#xff0c;可以通过QProcess类用于启动外部程序并与其进行通信.&#xff1b; 进程A&#xff08;…

微服务设计原则——高性能:锁

文章目录 1.锁的问题2.无锁2.1 串行无锁2.2 无锁数据结构 3.减少锁竞争参考文献 1.锁的问题 高性能系统中使用锁&#xff0c;往往带来的坏处要大于好处。 并发编程中&#xff0c;锁带解决了安全问题&#xff0c;同时也带来了性能问题&#xff0c;因为锁让并发处理变成了串行操…

海外营销推广:快速创建维基百科(wiki)词条-大舍传媒

一、维基百科的永久留存问题 许多企业和个人关心维基百科是否能永久留存。实际上&#xff0c;只要企业和个人的行为没有引起维基百科管理方的反感&#xff0c;词条就可以长期保存。如果有恶意行为或被投诉&#xff0c;维基百科可能会对词条进行删除或修改。 二、创建维基百科…

TCP与UDP网络编程

网络通信协议 java.net 包中提供了两种常见的网络协议的支持: UDP&#xff1a;用户数据报协议(User Datagram Protocol)TCP&#xff1a;传输控制协议(Transmission Control Protocol) TCP协议与UDP协议 TCP协议 TCP协议进行通信的两个应用进程&#xff1a;客户端、服务端 …

好玩的调度技术-场景编辑器

好玩的调度技术-场景编辑器 文章目录 好玩的调度技术-场景编辑器前言一、演示一、代码总结好玩系列 前言 这两天写前端写上瘾了&#xff0c;顺手做了个好玩的东西&#xff0c;好玩系列也好久没更新&#xff0c;正好作为素材写一篇文章&#xff0c;我真的觉得蛮好玩的&#xff…

LinuxShell编程1———shell基础命令

文章目录 前言 一、shell基础知识 1、shell概念 2、Shell的功能 接收&#xff1a;用户命令 调用&#xff1a;相应的应用程序 解释并交给&#xff1a;内核去处理 返还&#xff1a;内核处理结果 3、Shell种类&#xff08;了解&#xff09; 3.1、MS-DOS 3.2、Windows的…

R语言进行K折交叉验证问题

在使用R语言进行模型参数评估优化时候&#xff0c;会使用K折交叉验证&#xff0c;其中会遇到各种各样问题&#xff1a; 错误: C5.0 models require a factor outcome > (1-mean(E0));(1-mean(E1)) [1] 1 [1] 1 报错说明C5.0模型需要因子变量输出&#xff0c;源代码如下&am…

无人机技术优势及发展详解

一、技术优势 无人机&#xff08;Unmanned Aerial Vehicle&#xff0c;UAV&#xff09;作为一种新兴的空中智能平台&#xff0c;凭借其独特的技术优势&#xff0c;已经在众多领域中展现出强大的应用潜力和实用价值。以下是无人机的主要技术优势&#xff1a; 1. 自主导航与远程…

【Harmony】SCU暑期实训鸿蒙开发学习日记Day2

目录 Git 参考文章 常用操作 ArkTS的网络编程 Http编程 发送请求 GET POST 处理响应 JSON数据解析 处理响应头 错误处理 Web组件 用生命周期钩子实现登录验证功能 思路 代码示例 解读 纯记录学习日记&#xff0c;杂乱&#xff0c;误点的师傅可以掉了&#x1…

How to integrate GPT-4 model hosted on Azure with the gptstudio package

题意&#xff1a;怎样将托管在Azure上的GPT-4模型与gptstudio包集成&#xff1f; 问题背景&#xff1a; I am looking to integrate the OpenAI GPT-4 model into my application. Here are the details I have: Endpoint: https://xxxxxxxxxxxxxxx.openai.azure.com/Locatio…

LG 选择 Flutter 来增强其智能电视操作系统 webOS

可以这个话题会让大多数人困惑&#xff0c;2024 年了为什么还会冒出 webOS 这种老古董&#xff1f;然后 LG 为什么选择 webOS &#xff1f;现在为什么又选择 Flutter &#xff1f; 其实早在 Google I/O 发布 Flutter 3.22 版本的时候&#xff0c;就提到了 LG 选择 Flutter 来增…