Spring Boot 中使用 Quartz(二)動態設定 Scheduler

今天要跟大家接續上次Spring Boot 中使用 Quartz這篇文章。

從上篇文章中,大家可以發現,我們需要先在 Java 裡面定義好我們的 JobDetailTrigger,如:
QuartzConfig.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Configuration
public class QuartzConfig {

@Bean
public JobDetail testQuartz1() {
return JobBuilder.newJob(TestJob.class).withIdentity("testTask1").storeDurably().build();
}

@Bean
public Trigger testQuartzTrigger1() {
//5秒执行一次
SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(5)
.repeatForever();
return TriggerBuilder.newTrigger().forJob(testQuartz1())
.withIdentity("testTask1")
.withSchedule(scheduleBuilder)
.build();
}
}

或是使用 xml 的方式進行設定。

那有沒有可以動態的方式去產生或是設定 JobDetailTrigger 的方法呢?

Quick Start

首先,我需要建立一個 util

SchedulerUtil.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class SchedulerUtil {

public static JobDetail createJobDetail(String jobClass, String identity, String jobGroup, String description) throws ClassNotFoundException {
Class cls = Class.forName(jobClass);
return JobBuilder.newJob(cls).storeDurably()
.withIdentity(JobKey.jobKey(identity, jobGroup))
.withDescription(description)
.build();
}

public static Trigger createTrigger(JobDetail jobDetail, String cronExp) {
Trigger trigger = TriggerBuilder.newTrigger().forJob(jobDetail)
.withIdentity(jobDetail.getKey().getName(), jobDetail.getKey().getGroup())
.withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
.build();
return trigger;
}
}

然後建立一個 config

QuartzConfig.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Configuration
@AutoConfigureAfter(QuartzAutoConfiguration.class)
public class QuartzConfig {

@Autowired
private SchedulerFactoryBean schedulerFactoryBean;
@Autowired
private GameConfigService gameConfigService;

@PostConstruct
public void quartzScheduler() throws Exception {

schedulerFactoryBean.setOverwriteExistingJobs(false);
Scheduler scheduler = schedulerFactoryBean.getScheduler();

// 刪除舊的job
for (JobKey key : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(gameConfig.getGameName()))) {
scheduler.deleteJob(key);
}

JobDetail jobDetail = SchedulerUtil.createJobDetail(TestJob.class,"jobId", "groupname", "desc");
Trigger trigger = SchedulerUtil.createTrigger(jobDetail, "0/5 * * * * ?");
scheduler.scheduleJob(jobDetail, trigger);
}
}

上面這樣就是一個簡單的完成了

進階版 - 設定 Cron

假如,我們需要每天從 00:00:00 開始,每隔 30 秒就執行 job 呢?
我們可以參照上面的 cron 表達式寫法:

1
0/5 * * * * ?

如果我們需要設定的時間的秒數剛好可以被 60 整除,我們都可以利用上面的做法,但是如果是每隔 45 或是 90 秒呢?
我的解決方式會是將所一整天所有會產生的 cron 以天為單位都先列出來並加入到 scheduler 中。

以下為修改後的程式:

驗證

我的範例是,每隔 30 秒執行一次

1
select * from qrtz_cron_triggers

程式的 console log

謝謝您的支持與鼓勵

Ads