您好,登錄后才能下訂單哦!
這篇“怎么用SpringBoot實現動態添加定時任務功能”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“怎么用SpringBoot實現動態添加定時任務功能”文章吧。
最近的需求有一個自動發布的功能, 需要做到每次提交都要動態的添加一個定時任務
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 @Configuration public class SchedulerConfig { @Bean public TaskScheduler taskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setPoolSize(4); scheduler.setRemoveOnCancelPolicy(true); scheduler.setThreadNamePrefix("scheduling-task-"); return scheduler; } }
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 */ @AllArgsConstructor public 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<Object, Runnable> factory; * 創建任務 * * @param params params * @return task public Runnable create(Object params) { return factory.apply(params); } * 獲取 key * @return key public abstract String getKey(Object params); }
這個枚舉的作用是生成定時任務的 runnable 和 定時任務的唯一值, 方便后續維護
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 */ @Slf4j public 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); }
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); } }
這個類的作用是包裝實際執行任務, 以及提供調度器的執行方法
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 */ @Component public class TaskRegister implements DisposableBean { private final Map<String, TimedTask> taskMap = 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銷毀時將任務一起銷毀
@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實現動態添加定時任務功能”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。