钟日健
2022-05-18 ed41701a2954172d20b85da0ae01436375210840
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package org.springblade.modules.quartz.config;
 
import lombok.AllArgsConstructor;
import org.quartz.*;
import org.springblade.modules.quartz.entity.ScheduledJob;
import org.springblade.modules.quartz.enums.ScheduledStatus;
import org.springframework.stereotype.Component;
 
/**
 * 任务管理器
 * @author zhongrj
 * @since 2022-03-17
 */
@Component
@AllArgsConstructor
public class ScheduledManager {
    private final static String JOB_NAME = "TASK_";
 
    private final Scheduler scheduler;
 
    /**
     * 获取触发器key
     */
    private TriggerKey getTriggerKey(ScheduledJob scheduledJob){
        return TriggerKey.triggerKey(JOB_NAME + scheduledJob.getId());
    }
 
    /**
     * 获取jobKey
     */
    private JobKey getJobKey(ScheduledJob scheduledJob) {
        return JobKey.jobKey(JOB_NAME + scheduledJob.getId());
    }
 
    /**
     * 获取表达式触发器
     */
    public CronTrigger getCronTrigger(ScheduledJob scheduledJob) {
        try {
            return (CronTrigger) scheduler.getTrigger(getTriggerKey(scheduledJob));
        } catch (SchedulerException e) {
            throw new RuntimeException("获取定时任务CronTrigger出现异常", e);
        }
    }
 
    /**
     * 创建定时任务
     */
    public void createScheduledJob(ScheduledJob scheduledJob) {
        try {
            //构建job信息
            JobDetail jobDetail = JobBuilder.newJob(QuartzJob.class).withIdentity(getJobKey(scheduledJob)).build();
 
            //表达式调度构建器,可以根据scheduledJob修改withMisfireHandling方法,但是使用异步执行定时任务,没必要
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduledJob.getCronExpression())
                .withMisfireHandlingInstructionFireAndProceed();
 
            //按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(scheduledJob)).withSchedule(scheduleBuilder).build();
 
            //放入参数,运行时的方法可以获取
            jobDetail.getJobDataMap().put(QuartzJob.JOB_PARAM_KEY, scheduledJob);
 
            scheduler.scheduleJob(jobDetail, trigger);
 
            //暂停任务
            if (scheduledJob.getStatus().equals(ScheduledStatus.PAUSE.getType())) {
                pauseJob(scheduledJob);
            }
        } catch (SchedulerException e) {
            throw new RuntimeException("创建定时任务失败", e);
        }
    }
 
    /**
     * 更新定时任务
     */
    public void updateScheduledJob(ScheduledJob scheduleJob) {
        try {
            TriggerKey triggerKey = getTriggerKey(scheduleJob);
 
            //表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()).withMisfireHandlingInstructionFireAndProceed();
 
            CronTrigger trigger = getCronTrigger(scheduleJob);
 
            // 如果定时任务不存在,则创建定时任务
            if (trigger == null) {
                createScheduledJob(scheduleJob);
                return;
            }
 
            //按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
 
            //参数
            trigger.getJobDataMap().put(QuartzJob.JOB_PARAM_KEY, scheduleJob);
 
            scheduler.rescheduleJob(triggerKey, trigger);
 
            //暂停任务
            if (scheduleJob.getStatus().equals(ScheduledStatus.PAUSE.getType())) {
                pauseJob(scheduleJob);
            }
 
        } catch (SchedulerException e) {
            throw new RuntimeException("更新定时任务失败", e);
        }
    }
 
    /**
     * 立即执行任务
     */
    public void run(ScheduledJob scheduleJob) {
        try {
            //参数
            JobDataMap dataMap = new JobDataMap();
            dataMap.put(QuartzJob.JOB_PARAM_KEY, scheduleJob);
 
            scheduler.triggerJob(getJobKey(scheduleJob), dataMap);
        } catch (SchedulerException e) {
            throw new RuntimeException("立即执行定时任务失败", e);
        }
    }
 
 
    /**
     * 暂停任务
     */
    public void pauseJob(ScheduledJob scheduledJob) {
        try {
            scheduler.pauseJob(getJobKey(scheduledJob));
        } catch (SchedulerException e) {
            throw new RuntimeException("暂停定时任务失败", e);
        }
    }
 
    /**
     * 恢复任务
     */
    public void resumeJob(ScheduledJob scheduleJob) {
        try {
            scheduler.resumeJob(getJobKey(scheduleJob));
        } catch (SchedulerException e) {
            throw new RuntimeException("恢复定时任务失败", e);
        }
    }
 
    /**
     * 删除定时任务
     */
    public void deleteScheduledJob(ScheduledJob scheduleJob) {
        try {
            // 停止触发器
            scheduler.pauseTrigger(getTriggerKey(scheduleJob));
            //移除触发器
            scheduler.unscheduleJob(getTriggerKey(scheduleJob));
            //删除任务
            scheduler.deleteJob(getJobKey(scheduleJob));
        } catch (SchedulerException e) {
            throw new RuntimeException("删除定时任务失败", e);
        }
    }
 
}