一、引言
動態定時任務是指可以動態添加、修改、刪除定時任務的功能,一般應用於需要靈活控制定時任務的業務場景。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-hk/n/370018.html
微信掃一掃
支付寶掃一掃