懒羊羊
2023-08-30 1ac2bc1590406d9babec036e154d8d08f34a6aa1
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package cn.stylefeng.guns.modular.zsx.bs.job.quartz;
 
import cn.stylefeng.guns.modular.zsx.bs.job.constant.QuartzEnum;
import cn.stylefeng.guns.modular.zsx.bs.job.entity.SysJob;
import lombok.SneakyThrows;
import org.quartz.*;
import org.springframework.util.ObjectUtils;
 
import java.util.Date;
 
 
/**
 * @author fulin
 * @since 2023/6/14 15:23
 * <p>
 * 此类作为操作job的工具类,这里的job与quartz中的 JobDetail一一对应 ,包括任务的增删改 {@link JobDetail}
 * </p>
 */
public class QuartzUtil {
 
    /**
     * 将新增的任务放入quartz调度中心中执行
     *
     * @param sysJob 具体任务信息
     * @throws Exception 异常
     */
    @SneakyThrows
    public static void insertOrUpdateJob(SysJob sysJob) {
        // 获取调度器 Scheduler
        Scheduler scheduler = SchedulerStatic.getScheduler();
        Long jobId = sysJob.getId();
        String jobGroup = sysJob.getJobGroup();
 
        // 构造一个job
        JobKey jobKey = JobKey.jobKey(jobId.toString(), jobGroup);
        JobDetail jobDetail = JobBuilder
                .newJob(QuartzJob.class)
                .withIdentity(jobKey)
                .build();
 
        // 构造cron调度器
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(sysJob.getCronExpression());
        getMisfirePolicy(sysJob, cronScheduleBuilder);
 
        // 构造触发器 trigger
        TriggerKey triggerKey = TriggerKey.triggerKey(jobId.toString(), jobGroup);
        CronTrigger trigger = TriggerBuilder
                .newTrigger()
                .withIdentity(triggerKey)
                .withSchedule(cronScheduleBuilder)
                .build();
 
        // 放入job信息,为后续执行改任务的具体方法做铺垫(需要反射调用), 在execute中获取并应用
        jobDetail.getJobDataMap().put(QuartzEnum.jobKey, sysJob);
        // 判断该任务是否存在,修改任务,先删除然后添加
        if (scheduler.checkExists(jobKey)) {
            // 防止创建时存在数据问题 先移除,然后在执行创建操作
            scheduler.deleteJob(jobKey);
        }
        // 判断任务是否过期
        CronExpression cron = new CronExpression(sysJob.getCronExpression());
        Date nextValidTimeAfter = cron.getNextValidTimeAfter(new Date(System.currentTimeMillis()));
        if (!ObjectUtils.isEmpty(nextValidTimeAfter)) {
            // 执行调度任务
            scheduler.scheduleJob(jobDetail, trigger);
        }
        // 暂停任务
        if (sysJob.getStatus().equals(QuartzEnum.PAUSE)) {
            scheduler.pauseJob(jobKey);
        }
    }
 
 
    /**
     * 根据计划执行错误策略,设置调度器
     *
     * @param sysJob              任务信息
     * @param cronScheduleBuilder cron调度器
     */
    private static void getMisfirePolicy(SysJob sysJob, CronScheduleBuilder cronScheduleBuilder) {
        switch (sysJob.getMisfirePolicy()) {
            case QuartzEnum.MISFIRE_DEFAULT:
                break;
            case QuartzEnum.MISFIRE_IGNORE_MISFIRES:
                cronScheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires();
                break;
            case QuartzEnum.MISFIRE_FIRE_AND_PROCEED:
                cronScheduleBuilder.withMisfireHandlingInstructionFireAndProceed();
                break;
            case QuartzEnum.MISFIRE_DO_NOTHING:
                cronScheduleBuilder.withMisfireHandlingInstructionDoNothing();
                break;
            default:
                throw new RuntimeException("The task misfire policy '" + sysJob.getMisfirePolicy() + "' cannot be used in cron schedule tasks");
        }
    }
 
    /**
     * 删除任务
     *
     * @param sysJob 具体任务信息(获取jobkey)
     */
    @SneakyThrows
    public static void deleteJob(SysJob sysJob) {
        // 获取调度器 Scheduler
        Scheduler scheduler = SchedulerStatic.getScheduler();
        scheduler.deleteJob(JobKey.jobKey(sysJob.getId().toString(), sysJob.getJobGroup()));
    }
}