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