主要思路就是動態的變化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添加就完事兒了。
如果有不妥之處,希望網友指出。
看一百遍不如寫一遍,沖!
