主要思路就是动态的变化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添加就完事儿了。
如果有不妥之处,希望网友指出。
看一百遍不如写一遍,冲!