您好,登錄后才能下訂單哦!
這篇“怎么用SpringBoot實現(xiàn)動態(tài)添加定時任務(wù)功能”文章的知識點大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“怎么用SpringBoot實現(xiàn)動態(tài)添加定時任務(wù)功能”文章吧。
最近的需求有一個自動發(fā)布的功能, 需要做到每次提交都要動態(tài)的添加一個定時任務(wù)
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; /** * 調(diào)度器配置 * * @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; /** * 任務(wù)類型 * * @author Jiahang Li * @version 1.0.0 * @since 2022/2/14 10:16 */ @AllArgsConstructor public enum TaskType { /** * 發(fā)布任務(wù) */ RELEASE(id -> new ReleaseTaskImpl((Long) id)) { @Override public String getKey(Object params) { return Const.RELEASE + "-" + params; } }, * 調(diào)度任務(wù) SCHEDULER_TASK(id -> new SchedulerTaskImpl((Long) id)) { return Const.TASK + "-" + params; ; private final Function<Object, Runnable> factory; * 創(chuàng)建任務(wù) * * @param params params * @return task public Runnable create(Object params) { return factory.apply(params); } * 獲取 key * @return key public abstract String getKey(Object params); }
這個枚舉的作用是生成定時任務(wù)的 runnable 和 定時任務(wù)的唯一值, 方便后續(xù)維護
package com.orion.ops.handler.scheduler.impl; import com.orion.ops.service.api.ApplicationReleaseService; import com.orion.spring.SpringHolder; import lombok.extern.slf4j.Slf4j; /** * 發(fā)布任務(wù)實現(xiàn) * * @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("定時執(zhí)行發(fā)布任務(wù)-觸發(fā) 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; /** * 定時 任務(wù)包裝器 * * @author Jiahang Li * @version 1.0.0 * @since 2022/2/14 10:34 */ public class TimedTask { /** * 任務(wù) */ private Runnable runnable; * 異步執(zhí)行 private volatile ScheduledFuture<?> future; public TimedTask(Runnable runnable) { this.runnable = runnable; } * 提交任務(wù) 一次性 * * @param scheduler scheduler * @param time time public void submit(TaskScheduler scheduler, Date time) { this.future = scheduler.schedule(runnable, time); * 提交任務(wù) cron表達式 * @param trigger trigger public void submit(TaskScheduler scheduler, Trigger trigger) { this.future = scheduler.schedule(runnable, trigger); * 取消定時任務(wù) public void cancel() { if (future != null) { future.cancel(true); } }
這個類的作用是包裝實際執(zhí)行任務(wù), 以及提供調(diào)度器的執(zhí)行方法
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; /** * 任務(wù)注冊器 * * @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; /** * 提交任務(wù) * * @param type type * @param time time * @param params params */ public void submit(TaskType type, Date time, Object params) { // 獲取任務(wù) TimedTask timedTask = this.getTask(type, params); // 執(zhí)行任務(wù) timedTask.submit(scheduler, time); } * @param cron cron public void submit(TaskType type, String cron, Object params) { timedTask.submit(scheduler, new CronTrigger(cron)); * 獲取任務(wù) private TimedTask getTask(TaskType type, Object params) { // 生成任務(wù) Runnable runnable = type.create(params); String key = type.getKey(params); // 判斷是否存在任務(wù) if (taskMap.containsKey(key)) { throw Exceptions.init(MessageConst.TASK_PRESENT); } TimedTask timedTask = new TimedTask(runnable); taskMap.put(key, timedTask); return timedTask; * 取消任務(wù) 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(); }
這個類提供了執(zhí)行, 提交任務(wù)的api, 實現(xiàn) DisposableBean 接口, 便于在bean銷毀時將任務(wù)一起銷毀
@Resource private TaskRegister taskRegister; /** * 提交發(fā)布 */ @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); // 提交任務(wù) taskRegister.submit(TaskType.RELEASE, request.getTimedReleaseTime(), id); return id; }
以上就是關(guān)于“怎么用SpringBoot實現(xiàn)動態(tài)添加定時任務(wù)功能”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。