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