Spring的Quartz实现动态添加定时任务

主要思路就是动态的变化Schedule中的Job和cron

话不多说,直接上干货!

1.工具类。

 1 @Component
 2 public final class ScheduleTaskUtils {
 3 
 4     /**
 5      * 日志对象实例
 6      */
 7     private static final Logger LOGGER = LoggerFactory.getLogger(DynamicScheduleTaskUtils.class);
 8     private SchedulerFactoryBean schedulerFactoryBean;
 9 
10     @Autowired
11     public void setSchedulerFactoryBean(SchedulerFactoryBean schedulerFactoryBean) {
12         this.schedulerFactoryBean = schedulerFactoryBean;
13     }
14 
15     /**
16      * 该方法实现添加新的定时任务
17      *
18      * @param taskDetail 定时任务所需要的信息
19      */
20     public void addScheduleTask(@NotNull TaskDetail taskDetail) throws SchedulerException {
21         schedulerFactoryBean.setStartupDelay(taskDetail.getStartupDelay());
22         Scheduler scheduler = schedulerFactoryBean.getScheduler();
23         TriggerKey triggerKey = TriggerKey.triggerKey(taskDetail.getJobName(), taskDetail.getJobGroup());
24         CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
25         if (Objects.nonNull(cronTrigger)) {
26             LOGGER.error("任务[{}]已经在执行中,请不要重复添加", JSONUtil.toJsonStr(taskDetail));
27             return;
28         }
29         CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(taskDetail.getCronExpression());
30         Trigger trigger = TriggerBuilder.newTrigger().withIdentity(taskDetail.getJobName(), taskDetail.getJobGroup())
31                 .withSchedule(cronScheduleBuilder).build();
32         JobDetail jobDetail = JobBuilder.newJob(taskDetail.getJob().getClass()).withIdentity(taskDetail.getJobName(), taskDetail
33                 .getJobGroup()).build();
34         Map<String, Object> extraMap = taskDetail.getExtraMap();
35         if (CollectionUtil.isNotEmpty(extraMap)) {
36             jobDetail.getJobDataMap().putAll(extraMap);
37         }
38         scheduler.scheduleJob(jobDetail, trigger);
39     }
public class TaskDetail implements java.io.Serializable {

    /**
     * 执行任务的名称,该名称应当唯一并且具有一定的含义
     */
    private String jobName;

    /**
     * 执行任务的分组,该名称也应当唯一并且具有一定的含义
     */
    private String jobGroup;

    /**
     * 任务执行的表达式,表达式支持6或者7位
     */
    private String cronExpression;

    /**
     * 延时启动
     */
    private int startupDelay;

    /**
     * 需要执行的任务,
     */
    private Job job;

    /**
     * 扩展信息,添加在job的调用中需要使用到的各种参数
     */
    private Map<String, Object> extraMap;

    public String getJobName() {
        return jobName;
    }

    public void setJobName(String jobName) {
        this.jobName = jobName;
    }

    public String getJobGroup() {
        return jobGroup;
    }

    public void setJobGroup(String jobGroup) {
        this.jobGroup = jobGroup;
    }

    public String getCronExpression() {
        return cronExpression;
    }

    public void setCronExpression(String cronExpression) {
        this.cronExpression = cronExpression;
    }

    public int getStartupDelay() {
        return startupDelay;
    }

    public void setStartupDelay(int startupDelay) {
        this.startupDelay = startupDelay;
    }

    public Job getJob() {
        return job;
    }

    public void setJob(Job job) {
        this.job = job;
    }

    public Map<String, Object> getExtraMap() {
        return extraMap;
    }

    public void setExtraMap(Map<String, Object> extraMap) {
        this.extraMap = extraMap;
    }
}

2.动态定时任务的Job类

@Component
public class CancelOrderJob implements Job {

@Override
    public void execute(JobExecutionContext context) {
        //定时任务执行逻辑...
    }

}

3.动态的cron工具类

public final class CronExpressionUtils {
//封装一些动态的表达式
public static String getLaterCronExpression(int num, DateField dateField) {
       //...
    }

}

4.在需要添加定时器的时候,用ScheduleTaskUtils 工具类,传入TaskDetail添加就完事儿了。

如果有不妥之处,希望网友指出。

看一百遍不如写一遍,冲!

原文地址:https://www.cnblogs.com/codecodeandcode/p/12803009.html