最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot?實(shí)現(xiàn)動(dòng)態(tài)添加定時(shí)任務(wù)功能

 更新時(shí)間:2022年02月28日 11:44:38   作者:lijiahangmax  
這篇文章主要介紹了SpringBoot?動(dòng)態(tài)添加定時(shí)任務(wù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

最近的需求有一個(gè)自動(dòng)發(fā)布的功能, 需要做到每次提交都要?jiǎng)討B(tài)的添加一個(gè)定時(shí)任務(wù)

代碼結(jié)構(gòu)

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;
/**
 * 調(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;
    }
}

2. 定時(shí)任務(wù)類型枚舉

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);
}

這個(gè)枚舉的作用是生成定時(shí)任務(wù)的 runnable 和 定時(shí)任務(wù)的唯一值, 方便后續(xù)維護(hù)

3. 實(shí)際執(zhí)行任務(wù)實(shí)現(xiàn)類

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ù)實(shí)現(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("定時(shí)執(zhí)行發(fā)布任務(wù)-觸發(fā) releaseId: {}", releaseId);
        applicationReleaseService.runnableAppRelease(releaseId, true);
}

4. 定時(shí)任務(wù)包裝器

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;
/**
 * 定時(shí) 任務(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表達(dá)式
     * @param trigger   trigger
    public void submit(TaskScheduler scheduler, Trigger trigger) {
        this.future = scheduler.schedule(runnable, trigger);
     * 取消定時(shí)任務(wù)
    public void cancel() {
        if (future != null) {
            future.cancel(true);
        }
}

這個(gè)類的作用是包裝實(shí)際執(zhí)行任務(wù), 以及提供調(diào)度器的執(zhí)行方法

5. 任務(wù)注冊(cè)器 (核心)

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ù)注冊(cè)器
 *
 * @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();
}

這個(gè)類提供了執(zhí)行, 提交任務(wù)的api, 實(shí)現(xiàn) DisposableBean 接口, 便于在bean銷毀時(shí)將任務(wù)一起銷毀

6. 使用

    @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;
    }

最后

       這是一個(gè)簡單的動(dòng)態(tài)添加定時(shí)任務(wù)的工具, 有很多的改造空間, 比如想持久化可以插入到庫中, 定義一個(gè) CommandLineRunner 在啟動(dòng)時(shí)將定時(shí)任務(wù)全部加載, 還可以給任務(wù)加鉤子自動(dòng)提交,自動(dòng)刪除等, 代碼直接cv一定會(huì)報(bào)錯(cuò), 就是一些工具, 常量類會(huì)報(bào)錯(cuò), 改改就好了, 本人已親測(cè)可用, 有什么問題可以在評(píng)論區(qū)溝通

到此這篇關(guān)于SpringBoot 實(shí)現(xiàn)動(dòng)態(tài)添加定時(shí)任務(wù)功能的文章就介紹到這了,更多相關(guān)SpringBoot 定時(shí)任務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JVM內(nèi)置函數(shù)Intrinsics介紹

    JVM內(nèi)置函數(shù)Intrinsics介紹

    這篇文章主要介紹了JVM內(nèi)置函數(shù)Intrinsics,我們將學(xué)習(xí)什么是intrinsics(內(nèi)部/內(nèi)置函數(shù)),以及它們?nèi)绾卧贘ava和其他基于JVM的語言中工作,需要的朋友可以參考一下
    2022-02-02
  • Spring實(shí)戰(zhàn)之獲取其他Bean的屬性值操作示例

    Spring實(shí)戰(zhàn)之獲取其他Bean的屬性值操作示例

    這篇文章主要介紹了Spring實(shí)戰(zhàn)之獲取其他Bean的屬性值操作,結(jié)合實(shí)例形式分析了Spring操作Bean屬性值的相關(guān)配置與實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2019-12-12
  • Java判斷用戶名和密碼是否符合要求過程詳解

    Java判斷用戶名和密碼是否符合要求過程詳解

    這篇文章主要介紹了Java判斷用戶名和密碼過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Spring框架學(xué)習(xí)之Cache抽象詳解

    Spring框架學(xué)習(xí)之Cache抽象詳解

    這篇文章主要為大家介紹了Spring框架學(xué)習(xí)中Cache抽象詳解示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-10-10
  • 詳解spring切面使用傳遞給被通知方法的參數(shù)

    詳解spring切面使用傳遞給被通知方法的參數(shù)

    本篇文章主要介紹了詳解spring切面使用傳遞給被通知方法的參數(shù),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-12-12
  • Java線程池的幾種實(shí)現(xiàn)方法和區(qū)別介紹

    Java線程池的幾種實(shí)現(xiàn)方法和區(qū)別介紹

    下面小編就為大家?guī)硪黄狫ava線程池的幾種實(shí)現(xiàn)方法和區(qū)別。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考,一起跟隨小編過來看看吧,祝大家游戲愉快哦
    2016-05-05
  • SpringBoot 集成 Nebula的操作過程

    SpringBoot 集成 Nebula的操作過程

    這篇文章主要介紹了SpringBoot 集成 Nebula的操作過程,通過示例代碼介紹了java 環(huán)境下如何對(duì) Nebula Graph 進(jìn)行操作,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • java二維數(shù)組基礎(chǔ)知識(shí)詳解

    java二維數(shù)組基礎(chǔ)知識(shí)詳解

    這篇文章主要介紹了java二維數(shù)組基礎(chǔ)知識(shí)詳解的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • Java Calendar日歷類的使用介紹

    Java Calendar日歷類的使用介紹

    Candendar類是一個(gè)抽象類,提供了一些獲取當(dāng)前時(shí)間,或者指定的時(shí)間的字段和一些方法,我們可以通過一些方法與字段對(duì)他進(jìn)行獲取當(dāng)前天或者當(dāng)月的一些信息
    2022-09-09
  • Spring中Feign的調(diào)用流程詳解

    Spring中Feign的調(diào)用流程詳解

    這篇文章主要介紹了Spring中Feign的調(diào)用流程詳解,分析過了創(chuàng)建的代理是FeignInvocationHandler,那我們就打斷點(diǎn),停在它的反射方法上,看看到底做了什么,需要的朋友可以參考下
    2023-11-11

最新評(píng)論

乌拉特后旗| 海淀区| 彭泽县| 文登市| 郎溪县| 得荣县| 苍山县| 修文县| 历史| 泰宁县| 区。| 西畴县| 文水县| 竹山县| 彭州市| 金沙县| 巫山县| 威信县| 安西县| 盐亭县| 郑州市| 安徽省| 广饶县| 曲沃县| 元氏县| 安康市| 梅州市| 祁阳县| 肃宁县| 双牌县| 方正县| 鄂州市| 通州区| 东兴市| 唐山市| 玉山县| 巴里| 巴塘县| 曲周县| 莱西市| 隆昌县|