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

spring動態(tài)控制定時任務(wù)的實(shí)現(xiàn)

 更新時間:2024年01月08日 11:29:40   作者:QiHY  
在實(shí)際項(xiàng)目中,經(jīng)常需要動態(tài)的控制定時任務(wù),比如通過接口增加、啟動、停止、刪除定時任務(wù),本文主要介紹了spring動態(tài)控制定時任務(wù)的實(shí)現(xiàn),感興趣的可以了解一下

在spring框架中,對于簡單的定時任務(wù),可以使用 @Scheduled 注解實(shí)現(xiàn),在實(shí)際項(xiàng)目中,經(jīng)常需要動態(tài)的控制定時任務(wù),比如通過接口增加、啟動、停止、刪除定時任務(wù),動態(tài)的改變定時任務(wù)的執(zhí)行時間等。

我們可以通過編碼的方式動態(tài)控制定時任務(wù),具體的代碼參照 示例項(xiàng)目 https://github.com/qihaiyan/springcamp/tree/master/spring-dynamic-scheduler

一、概述

在spring框架可以通過 CronTask 和 TaskScheduler 動態(tài)控制定時任務(wù),實(shí)現(xiàn)定時任務(wù)的動態(tài)更新,比如修改定時任務(wù)的執(zhí)行時間,這個是 @Scheduled 無法實(shí)現(xiàn)的。采用編碼控制動態(tài)任務(wù)的方式,我們還可以把動態(tài)任務(wù)執(zhí)行信息保存到數(shù)據(jù)庫中,通過數(shù)據(jù)庫里的任務(wù)配置數(shù)據(jù)來動態(tài)控制定時任務(wù),也可以通過接口來動態(tài)控制定時任務(wù)。

二、配置定時任務(wù)

首先,同 @Scheduled 注解的方式一樣,動態(tài)控制定時任務(wù)也需要使用 @EnableScheduling 注解來開啟定時任務(wù)功能:

然后通過實(shí)現(xiàn) SchedulingConfigurer 接口來對動態(tài)任務(wù)進(jìn)行配置:

@Component
public class MyScheduler implements SchedulingConfigurer {
    private ScheduledTaskRegistrar taskRegistrar;
    private final ConcurrentHashMap<Long, ScheduledFuture<?>> scheduledFutures = new ConcurrentHashMap<>();

    @Override
    public void configureTasks(@NonNull ScheduledTaskRegistrar taskRegistrar) {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
        threadPoolTaskScheduler.setPoolSize(10);// Set the pool of threads
        threadPoolTaskScheduler.setThreadNamePrefix("sys-scheduler");
        threadPoolTaskScheduler.initialize();
        this.taskRegistrar = taskRegistrar;
        this.taskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
    }

    @PreDestroy
    public void destroy() {
        this.taskRegistrar.destroy();
    }
}

通過上面的代碼,我們就啟用了動態(tài)任務(wù)的基本能力,為動態(tài)任務(wù)指定了執(zhí)行線程池。

三、動態(tài)更新定時任務(wù)

更新定時任務(wù)通過 CronTask 和 TaskScheduler 來實(shí)現(xiàn),我們新增一個注冊定時任務(wù)的方法:

    public void registerTask(TaskData taskData) {
        //如果配置一致,則不需要重新創(chuàng)建定時任務(wù)
        if (scheduledFutures.containsKey(taskData.getId())
                && cronTasks.get(taskData.getId()).getExpression().equals(taskData.getExpression())) {
            return;
        }
        //如果策略執(zhí)行時間發(fā)生了變化,則取消當(dāng)前策略的任務(wù)
        if (scheduledFutures.containsKey(taskData.getId())) {
            scheduledFutures.remove(taskData.getId()).cancel(false);
            cronTasks.remove(taskData.getId());
        }

        CronTask task = new CronTask(taskData, taskData.getExpression());
        TaskScheduler scheduler = taskRegistrar.getScheduler();
        if (scheduler != null) {
            ScheduledFuture<?> future = scheduler.schedule(task.getRunnable(), task.getTrigger());
            if (future != null) {
                scheduledFutures.put(taskData.getId(), future);
            }
        }
    }

我們新增了一個 registerTask 方法用于注冊定時任務(wù),入?yún)⒅?TaskData 是定時任務(wù)的配置數(shù)據(jù),為了簡單,我們把配置數(shù)據(jù)和執(zhí)行代碼放到了一起:

@Slf4j
@Data
@Entity
public class TaskData implements Runnable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String expression;

    @Transient
    @Override
    public void run() {
        log.info("{} is running with expression {}", this.getName(), this.getExpression());
    }
}

核心代碼是創(chuàng)建一個 CronTask 對象,該對象包含兩個參數(shù):Runnable 方法和 cron 表達(dá)式。
CronTask 對象創(chuàng)建好后,通過 ScheduledTaskRegistrar 對定時任務(wù)進(jìn)行注冊,注冊完成后,定時任務(wù)就會在cron表達(dá)式指定的時間點(diǎn)開始執(zhí)行了。
執(zhí)行的代碼就是 Runnable 參數(shù)指定的方法。

四、動態(tài)停止定時任務(wù)

為了能夠動態(tài)停止定時任務(wù),我們在注冊定時任務(wù)時,把注冊結(jié)果放到了一個Map中:

private final ConcurrentHashMap<Long, ScheduledFuture<?>> scheduledFutures = new ConcurrentHashMap<>();

ScheduledFuture<?> future = scheduler.schedule(task.getRunnable(), task.getTrigger());
            if (future != null) {
                scheduledFutures.put(taskData.getId(), future);
            }

新增停止定時任務(wù)的方法:

public void stop(Long id) {
        if (scheduledFutures.containsKey(id)) {
            scheduledFutures.remove(id).cancel(false);
        }
    }

該方法需要傳入定時任務(wù)的id,由于我們把定時任務(wù)信息保存到了 scheduledFutures 這個Map中,所以可以根據(jù)任務(wù)id參數(shù)查找到對應(yīng)的定時任務(wù)信息,然后調(diào)用對應(yīng)的 cancel方法來停止定時任務(wù)。

五、通過接口控制定時任務(wù)

通過上面的步驟我們已經(jīng)具備了動態(tài)控制定時任務(wù)的基本能力,下面增加接口來控制定時任務(wù):

@EnableScheduling
@SpringBootApplication
@RestController
public class DemoApplication {
    @Autowired
    private MyScheduler myScheduler;
    @Autowired
    private TaskDataRepository taskDataRepository;

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @RequestMapping("/register")
    public TaskData register(
            String name,
            @RequestParam(name = "expression", required = false, defaultValue = "0/1 * * * * ?") String expression
    ) {
        TaskData taskData = taskDataRepository.findOneByName(name).orElse(new TaskData());
        taskData.setName(name);
        taskData.setExpression(expression);
        taskData = taskDataRepository.save(taskData);
        myScheduler.registerTask(taskData);
        return taskData;
    }

    @RequestMapping("/stop")
    public void stop(Long id) {
        taskDataRepository.findById(id).ifPresent(taskData -> {
            myScheduler.stop(id);
        });
    }
}

我們提供了 register 和 stop 兩個接口,這兩個接口會在改變動態(tài)任務(wù)執(zhí)行數(shù)據(jù)時,先將數(shù)據(jù)保存到數(shù)據(jù)庫中,對定時任務(wù)進(jìn)行持久化,避免程序重啟后定時任務(wù)都丟失。

程序啟動后,我們首先調(diào)用 register 接口新增一個定時任務(wù):

http://localhost:8080/register?name=test

接口調(diào)用后,在日志中可以看到定時任務(wù)開始執(zhí)行了:

2024-01-07T18:02:09.003+08:00  INFO 23012 --- [ sys-scheduler5] c.s.springdynamicscheduler.TaskData      : test is running with expression 0/1 * * * * ?
2024-01-07T18:02:10.005+08:00  INFO 23012 --- [ sys-scheduler3] c.s.springdynamicscheduler.TaskData      : test is running with expression 0/1 * * * * ?
2024-01-07T18:02:11.012+08:00  INFO 23012 --- [ sys-scheduler3] c.s.springdynamicscheduler.TaskData      : test is running with expression 0/1 * * * * ?

再調(diào)用 stop 接口,通過日志可以發(fā)現(xiàn)定時任務(wù)停止了執(zhí)行:

http://localhost:8080/stop?id=1

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

相關(guān)文章

  • SpringBoot項(xiàng)目jar依賴問題報錯解析

    SpringBoot項(xiàng)目jar依賴問題報錯解析

    本文主要介紹了Spring Boot項(xiàng)目中常見的依賴錯誤類型、報錯內(nèi)容及解決方法,依賴沖突包括類找不到、方法找不到、類型轉(zhuǎn)換異常等,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2025-12-12
  • IDEA中關(guān)于enter鍵換行的問題

    IDEA中關(guān)于enter鍵換行的問題

    這篇文章主要介紹了IDEA中關(guān)于enter鍵換行的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • java中Hashmap的get方法使用

    java中Hashmap的get方法使用

    這篇文章主要介紹了java中Hashmap的get方法使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • SpringBoot如何統(tǒng)一清理數(shù)據(jù)

    SpringBoot如何統(tǒng)一清理數(shù)據(jù)

    這篇文章主要介紹了SpringBoot如何統(tǒng)一清理數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Spring案例打印機(jī)的實(shí)現(xiàn)過程詳解

    Spring案例打印機(jī)的實(shí)現(xiàn)過程詳解

    這篇文章主要介紹了Spring案例打印機(jī)的實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • Springboot一個注解搞定返回參數(shù)key轉(zhuǎn)換功能

    Springboot一個注解搞定返回參數(shù)key轉(zhuǎn)換功能

    平時在搬磚的時候,大家有沒有遇到過這樣場景,由于各種因素導(dǎo)致,一個接口返回的數(shù)據(jù)里面的key是A,?但是客戶端(前端)要求返回的key不叫A叫Aa?。也就是返回的值不變,就是key換了。本文將通過一個注解搞定返回參數(shù)key轉(zhuǎn)換,需要的可以了解一下
    2022-10-10
  • java清除u盤內(nèi)存卡里的垃圾文件示例

    java清除u盤內(nèi)存卡里的垃圾文件示例

    手機(jī)內(nèi)存卡空間被用光了,但又不知道哪個文件占用了太大,一個個文件夾去找又太麻煩,開發(fā)了個小程序把手機(jī)所有文件(包括路徑下所有層次子文件夾下的文件)進(jìn)行一個排序,這樣你就可以找出哪個文件占用了內(nèi)存太大了
    2014-02-02
  • MyBatis-Plus中AutoGenerator的使用案例

    MyBatis-Plus中AutoGenerator的使用案例

    AutoGenerator是MyBatis-Plus的代碼生成器,通過?AutoGenerator?可以快速生成?Pojo、Mapper、?Mapper?XML、Service、Controller?等各個模塊的代碼,這篇文章主要介紹了MyBatis-Plus中AutoGenerator的詳細(xì)使用案例,需要的朋友可以參考下
    2023-05-05
  • SpringBoot2.0如何自定義404頁面渲染

    SpringBoot2.0如何自定義404頁面渲染

    這篇文章主要介紹了SpringBoot2.0如何自定義404頁面渲染問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • java通過復(fù)選框控件數(shù)組實(shí)現(xiàn)添加多個復(fù)選框控件示例分享

    java通過復(fù)選框控件數(shù)組實(shí)現(xiàn)添加多個復(fù)選框控件示例分享

    編寫程序,通過復(fù)選框控件數(shù)組事先選擇用戶愛好信息的復(fù)選框,在該程序中,要求界面中的復(fù)選框數(shù)量可以根據(jù)指定復(fù)選框名稱的字符串?dāng)?shù)組的長度來自動調(diào)節(jié)
    2014-02-02

最新評論

闻喜县| 邛崃市| 延边| 得荣县| 建阳市| 平昌县| 和龙市| 鄂温| 泉州市| 道真| 阿鲁科尔沁旗| 独山县| 象山县| 宝丰县| 桂林市| 兴义市| 股票| 普兰店市| 兴安县| 察雅县| 景德镇市| 庆城县| 喜德县| 子长县| 八宿县| 中阳县| 志丹县| 南丹县| 正阳县| 大丰市| 武宁县| 石屏县| 寻甸| 贵德县| 兴业县| 沛县| 中宁县| 平昌县| 杭州市| 三门县| 富顺县|