怎么用SpringBoot实现动态添加定时任务功能
发表于:2025-01-18 作者:千家信息网编辑
千家信息网最后更新 2025年01月18日,这篇"怎么用SpringBoot实现动态添加定时任务功能"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我
千家信息网最后更新 2025年01月18日怎么用SpringBoot实现动态添加定时任务功能
这篇"怎么用SpringBoot实现动态添加定时任务功能"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"怎么用SpringBoot实现动态添加定时任务功能"文章吧。
最近的需求有一个自动发布的功能, 需要做到每次提交都要动态的添加一个定时任务
代码结构
1. 配置类
package com.orion.ops.config; import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.TaskScheduler;import org.springframework.scheduling.annotation.EnableScheduling;import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;/** * 调度器配置 * * @author Jiahang Li * @version 1.0.0 * @since 2022/2/14 9:51 */@EnableScheduling@Configurationpublic class SchedulerConfig { @Bean public TaskScheduler taskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setPoolSize(4); scheduler.setRemoveOnCancelPolicy(true); scheduler.setThreadNamePrefix("scheduling-task-"); return scheduler; }}
2. 定时任务类型枚举
package com.orion.ops.handler.scheduler; import com.orion.ops.consts.Const;import com.orion.ops.handler.scheduler.impl.ReleaseTaskImpl;import com.orion.ops.handler.scheduler.impl.SchedulerTaskImpl;import lombok.AllArgsConstructor;import java.util.function.Function;/** * 任务类型 * * @author Jiahang Li * @version 1.0.0 * @since 2022/2/14 10:16 */@AllArgsConstructorpublic enum TaskType { /** * 发布任务 */ RELEASE(id -> new ReleaseTaskImpl((Long) id)) { @Override public String getKey(Object params) { return Const.RELEASE + "-" + params; } }, * 调度任务 SCHEDULER_TASK(id -> new SchedulerTaskImpl((Long) id)) { return Const.TASK + "-" + params; ; private final Function
这个枚举的作用是生成定时任务的 runnable 和 定时任务的唯一值, 方便后续维护
3. 实际执行任务实现类
package com.orion.ops.handler.scheduler.impl; import com.orion.ops.service.api.ApplicationReleaseService;import com.orion.spring.SpringHolder;import lombok.extern.slf4j.Slf4j;/** * 发布任务实现 * * @author Jiahang Li * @version 1.0.0 * @since 2022/2/14 10:25 */@Slf4jpublic class ReleaseTaskImpl implements Runnable { protected static ApplicationReleaseService applicationReleaseService = SpringHolder.getBean(ApplicationReleaseService.class); private Long releaseId; public ReleaseTaskImpl(Long releaseId) { this.releaseId = releaseId; } @Override public void run() { log.info("定时执行发布任务-触发 releaseId: {}", releaseId); applicationReleaseService.runnableAppRelease(releaseId, true);}
4. 定时任务包装器
package com.orion.ops.handler.scheduler; import org.springframework.scheduling.TaskScheduler;import org.springframework.scheduling.Trigger;import java.util.Date;import java.util.concurrent.ScheduledFuture;/** * 定时 任务包装器 * * @author Jiahang Li * @version 1.0.0 * @since 2022/2/14 10:34 */public class TimedTask { /** * 任务 */ private Runnable runnable; * 异步执行 private volatile ScheduledFuture> future; public TimedTask(Runnable runnable) { this.runnable = runnable; } * 提交任务 一次性 * * @param scheduler scheduler * @param time time public void submit(TaskScheduler scheduler, Date time) { this.future = scheduler.schedule(runnable, time); * 提交任务 cron表达式 * @param trigger trigger public void submit(TaskScheduler scheduler, Trigger trigger) { this.future = scheduler.schedule(runnable, trigger); * 取消定时任务 public void cancel() { if (future != null) { future.cancel(true); }}
这个类的作用是包装实际执行任务, 以及提供调度器的执行方法
5. 任务注册器 (核心)
package com.orion.ops.handler.scheduler; import com.orion.ops.consts.MessageConst;import com.orion.utils.Exceptions;import com.orion.utils.collect.Maps;import org.springframework.beans.factory.DisposableBean;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.scheduling.TaskScheduler;import org.springframework.scheduling.support.CronTrigger;import org.springframework.stereotype.Component;import javax.annotation.Resource;import java.util.Date;import java.util.Map;/** * 任务注册器 * * @author Jiahang Li * @version 1.0.0 * @since 2022/2/14 10:46 */@Componentpublic class TaskRegister implements DisposableBean { private final MaptaskMap = Maps.newCurrentHashMap(); @Resource @Qualifier("taskScheduler") private TaskScheduler scheduler; /** * 提交任务 * * @param type type * @param time time * @param params params */ public void submit(TaskType type, Date time, Object params) { // 获取任务 TimedTask timedTask = this.getTask(type, params); // 执行任务 timedTask.submit(scheduler, time); } * @param cron cron public void submit(TaskType type, String cron, Object params) { timedTask.submit(scheduler, new CronTrigger(cron)); * 获取任务 private TimedTask getTask(TaskType type, Object params) { // 生成任务 Runnable runnable = type.create(params); String key = type.getKey(params); // 判断是否存在任务 if (taskMap.containsKey(key)) { throw Exceptions.init(MessageConst.TASK_PRESENT); } TimedTask timedTask = new TimedTask(runnable); taskMap.put(key, timedTask); return timedTask; * 取消任务 public void cancel(TaskType type, Object params) { TimedTask task = taskMap.get(key); if (task != null) { taskMap.remove(key); task.cancel(); * 是否存在 public boolean has(TaskType type, Object params) { return taskMap.containsKey(type.getKey(params)); @Override public void destroy() { taskMap.values().forEach(TimedTask::cancel); taskMap.clear();}
这个类提供了执行, 提交任务的api, 实现 DisposableBean 接口, 便于在bean销毁时将任务一起销毁
6. 使用
@Resource private TaskRegister taskRegister; /** * 提交发布 */ @RequestMapping("/submit") @EventLog(EventType.SUBMIT_RELEASE) public Long submitAppRelease(@RequestBody ApplicationReleaseRequest request) { Valid.notBlank(request.getTitle()); Valid.notNull(request.getAppId()); Valid.notNull(request.getProfileId()); Valid.notNull(request.getBuildId()); Valid.notEmpty(request.getMachineIdList()); TimedReleaseType timedReleaseType = Valid.notNull(TimedReleaseType.of(request.getTimedRelease())); if (TimedReleaseType.TIMED.equals(timedReleaseType)) { Date timedReleaseTime = Valid.notNull(request.getTimedReleaseTime()); Valid.isTrue(timedReleaseTime.compareTo(new Date()) > 0, MessageConst.TIMED_GREATER_THAN_NOW); } // 提交 Long id = applicationReleaseService.submitAppRelease(request); // 提交任务 taskRegister.submit(TaskType.RELEASE, request.getTimedReleaseTime(), id); return id; }
以上就是关于"怎么用SpringBoot实现动态添加定时任务功能"这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注行业资讯频道。
任务
内容
功能
动态
包装
调度
作用
实际
文章
知识
篇文章
类型
生成
配置
一次性
代码
价值
大部分
就是
接口
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络安全工作的目标信息
触犯网络安全法去自首
网络安全企业排名名单
江苏根荣互联网科技
中世博联网络技术公司
服务器配置命令
电脑方舟服务器模组介绍
抗疫主题网络安全大赛作文
天堂2服务器设置
华科网络安全研究院报名情况
宿舍管理系统软件开发
象山直销软件开发项目
ftp 免费服务器
金蝶客户端连不上服务器
网络技术工程师英语作文
判断网站数据库类型
服务器不认硬盘怎么解决
五中全会网络安全
sun服务器维修电话
hive从本地导入数据库
数据库1002错误码
数据库集群软件解压
现在王者荣耀服务器几点关闭
陶家润泽谷数据库
企业网络安全论文答辩问题
林业局网络安全执法自查总结
网络安全断网事件
美国网络技术领先
抖音登录服务器错误怎么办
网络安全大赛cbf