一、引言
動態定時任務是指可以動態添加、修改、刪除定時任務的功能,一般應用於需要靈活控制定時任務的業務場景。SpringBoot作為一個非常火熱的Java框架,提供了非常便捷的定時任務的實現方式,本文主要介紹如何使用SpringBoot實現動態定時任務。下面我們將從多個方面進行詳細的闡述。
二、定時任務的基本實現方式
SpringBoot中基於註解的定時任務實現方式非常便捷,只需在任務方法上添加註解@Scheduled即可實現簡單的定時任務功能。例如,在SpringBoot應用程序中,執行某個方法,每隔一段時間輸出某個信息,可以使用如下注解配置:
@Scheduled(fixedRate = 5000) public void reportCurrentTime() { logger.info("當前時間是:{}", dateFormat.format(new Date())); }
上述代碼中,@Scheduled註解指示該方法應該執行一個定時任務,fixedRate是一個參數,它規定任務每隔多少毫秒執行一次。在這種情況下,任務將每隔5秒查詢一次數據庫並記錄當前時間。但是,這種方法只適合固定間隔的任務,如果想要控制任務的實現,就需要使用Cron表達式來定義定時策略。例如:
@Scheduled(cron = "0 15 10 ? * *") public void scheduledTask() { // 執行任務 }
上述代碼中,@Scheduled註解中通過cron屬性設置了一個Cron表達式,它表示任務將在每天的上午10點15分執行。
三、動態定時任務的實現方式
1. 存儲定時任務信息
為了實現動態定時任務的功能,我們需要在數據庫中存儲定時任務的相關信息,如任務名稱、任務描述、Cron表達式等。
我們可以建立一個定時任務數據表,將任務的相關信息存儲在該表中。
CREATE TABLE `task_schedule` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任務ID', `job_name` varchar(64) NOT NULL COMMENT '任務名稱', `job_desc` varchar(256) DEFAULT NULL COMMENT '任務描述', `job_group` varchar(64) DEFAULT NULL COMMENT '任務所屬分組', `job_cron` varchar(64) NOT NULL COMMENT 'Cron表達式', `job_status` int(2) NOT NULL COMMENT '任務狀態,1:啟用,0:禁用', `job_start_time` datetime DEFAULT NULL COMMENT '任務開始時間', `job_end_time` datetime DEFAULT NULL COMMENT '任務結束時間', `create_time` datetime NOT NULL COMMENT '任務創建時間', `update_time` datetime DEFAULT NULL COMMENT '任務更新時間', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='動態任務調度表';
2. 使用Quartz實現動態定時任務
SpringBoot集成了Quartz,並且提供了官方的Quartz工具包starter,因此,我們可以基於Quartz實現動態定時任務。
2.1 添加依賴
首先我們需要添加Quartz相關的依賴和SpringBoot的依賴。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
2.2 實現動態添加任務
SpringBoot提供了一個SchedulerFactoryBean來配置Quartz,我們可以通過SchedulerFactoryBean創建調度工廠,並使用任務調度工廠創建Scheduler調度器。下面我們來實現動態添加任務的代碼。
/** * 任務調度核心類 */ @Configuration public class QuartzConfig { @Autowired private DataSource dataSource; /** * 配置SchedulerFactoryBean */ @Bean public SchedulerFactoryBean schedulerFactoryBean() { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); // 加載quartz數據源 schedulerFactoryBean.setDataSource(dataSource); return schedulerFactoryBean; } /** * 創建Scheduler定時器 */ @Bean public Scheduler scheduler() throws SchedulerException { return schedulerFactoryBean().getScheduler(); } /** * 添加任務 * @param jobName 任務名稱 * @param jobGroup 任務分組 * @param cronExpression Cron表達式 * @param jobClass 任務類 * @throws SchedulerException */ public void addJob(String jobName, String jobGroup, String cronExpression, Class jobClass) throws SchedulerException { // 獲取調度器 Scheduler scheduler = scheduler(); // 構建任務信息 JobDetail jobDetail = JobBuilder.newJob(jobClass) .withIdentity(jobName, jobGroup) .build(); // 設置任務觸發器 CronTrigger cronTrigger = TriggerBuilder.newTrigger() .withIdentity(jobName, jobGroup) .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)) .build(); // 調度器中添加任務 scheduler.scheduleJob(jobDetail, cronTrigger); // 啟動調度器 if(!scheduler.isShutdown()) { scheduler.start(); } } }
上述代碼中,我們定義了一個SchedulerFactoryBean的Bean,並通過@Autowired註解將數據源注入到該Bean中。然後通過該Bean的方法getScheduler()獲取到Scheduler調度器。
可以看到,我們通過Quartz提供的JobBuilder和TriggerBuilder創建JobDetail和CronTrigger決定了動態定時任務的任務執行和觸發方式。最後調用調度器的方法scheduleJob()將任務添加到調度器中。
2.3 動態添加任務的調用
我們可以在任意位置調用添加任務方法addJob(),從而實現動態添加任務的功能。
@Autowired private QuartzConfig quartzConfig; public boolean addTask(String jobName, String jobGroup, String cron, Class jobClass) { try { quartzConfig.addJob(jobName, jobGroup, cron, jobClass); return true; } catch (SchedulerException e) { // ... return false; } }
2.4 動態修改任務
動態修改任務需要調用Quartz的Scheduler修改任務,我們可以在上一步的代碼中添加該功能。
/** * 修改任務 * @param jobName 任務名稱 * @param jobGroup 任務分組 * @param cronExpression Cron表達式 * @throws SchedulerException */ public void modifyJob(String jobName, String jobGroup, String cronExpression) throws SchedulerException { // 獲取調度器 Scheduler scheduler = scheduler(); // 根據任務名稱和分組名稱獲取任務Key TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup); // 根據任務Key獲取Trigger CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey); // 重新設置Cron表達式 CronScheduleBuilder builder = CronScheduleBuilder.cronSchedule(cronExpression); CronTrigger newTrigger = cronTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(builder).build(); // 重置觸發器中的Cron表達式 scheduler.rescheduleJob(triggerKey, newTrigger); }
2.5 動態刪除任務
在Quartz中刪除任務需要調用Scheduler刪除任務,Quartz提供了暫停、恢復和刪除任務的方法,我們可以基於這些方法實現動態刪除任務的功能。
/** * 刪除任務 * @param jobName 任務名稱 * @param jobGroup 任務分組 * @throws SchedulerException */ public void deleteJob(String jobName, String jobGroup) throws SchedulerException { // 獲取調度器 Scheduler scheduler = scheduler(); // 根據任務名稱和分組名稱獲取任務Key JobKey jobKey = JobKey.jobKey(jobName, jobGroup); // 刪除任務 scheduler.deleteJob(jobKey); }
四、總結
本文詳細介紹了如何使用SpringBoot實現動態定時任務功能,從定時任務的基本實現方式到動態定時任務的實現方式,逐步展示了動態定時任務的全過程,相信讀完本文後,你已經掌握了使用SpringBoot實現動態定時任務的方法。
原創文章,作者:OXHMK,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/370018.html