1.工具类
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.TriggerTask;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.stereotype.Component;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@Component
@Slf4j
public class ScheduleUtils implements InitializingBean {
@Autowired
private ScheduleLogMapper logMapper;
@Value("${emailAlarm.maxSize:5}")
private int poolSize;
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
private Map<String, ScheduleInfo> scheduledTaskMap = new ConcurrentHashMap<>();
private final DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
private static final String CRON = "cron";
private static final String PERIOD = "period";
@Override
public void afterPropertiesSet() {
threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(poolSize);
threadPoolTaskScheduler.setThreadNamePrefix("EmailAlarm-");
threadPoolTaskScheduler.setRemoveOnCancelPolicy(true);
threadPoolTaskScheduler.setAwaitTerminationSeconds(5);
threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);
threadPoolTaskScheduler.initialize();
}
/**
* 添加任务
* @param scheduleInfo
* @param triggerTask
*/
public void addTriggerTask(ScheduleInfo scheduleInfo, TriggerTask triggerTask) {
if (hasTask(scheduleInfo.getTaskId())) {
cancelTriggerTask(scheduleInfo.getTaskId());
}
ScheduledFuture<?> scheduledFuture = null;
try {
scheduledFuture = threadPoolTaskScheduler.schedule(triggerTask.getRunnable(), triggerTask.getTrigger());
} catch (Exception e) {
ScheduleLog scheduleLog = new ScheduleLog();
scheduleLog.setTaskId(scheduleInfo.getTaskId());
scheduleLog.setType(scheduleInfo.getType());
scheduleLog.setStatus(0);
scheduleLog.setError(e.getMessage());
logMapper.save(scheduleLog);
throw new IllegalArgumentException("添加任务失败,taskId:"+scheduleInfo.getTaskId());
}
if (scheduledFuture != null) {
scheduleInfo.setFuture(scheduledFuture);
scheduledTaskMap.put(scheduleInfo.getTaskId(), scheduleInfo);
}
}
/**
* 取消任务
* @param taskId
*/
public void cancelTriggerTask(String taskId) {
ScheduleInfo scheduleInfo = scheduledTaskMap.get(taskId);
if (scheduleInfo == null) {
return;
}
ScheduledFuture<?> scheduledFuture = scheduleInfo.getFuture();
if (scheduledFuture != null) {
scheduledFuture.cancel(true);
}
scheduledTaskMap.remove(taskId);
}
/**
* 重置任务
* @param scheduleInfo
* @param triggerTask
*/
public void resetTriggerTask(ScheduleInfo scheduleInfo, TriggerTask triggerTask) {
cancelTriggerTask(scheduleInfo.getTaskId());
addTriggerTask(scheduleInfo, triggerTask);
}
public boolean hasTask(String taskId) {
return scheduledTaskMap.containsKey(taskId);
}
public void addCronTriggerTask(ScheduleInfo scheduleInfo) {
Runnable task = () -> {
ScheduleLog scheduleLog = new ScheduleLog();
scheduleLog.setTaskId(scheduleInfo.getTaskId());
scheduleLog.setType(scheduleInfo.getType());
scheduleLog.setStatus(1);
logMapper.save(scheduleLog);
log.info("[ScheduledConfig] CronTrigger...time is {},{}", format.format(new Date()),scheduleInfo.getTaskId());
};
Trigger trigger = new AbstractTrigger(scheduleInfo) {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
return new CronTrigger(getScheduleInfo().getCron()).nextExecutionTime(triggerContext);
}
};
addTriggerTask(scheduleInfo, new TriggerTask(task, trigger));
}
public void addPeriodicTriggerTask(ScheduleInfo scheduleInfo) {
Runnable task = () -> {
ScheduleLog scheduleLog = new ScheduleLog();
scheduleLog.setTaskId(scheduleInfo.getTaskId());
scheduleLog.setType(scheduleInfo.getType());
scheduleLog.setStatus(1);
logMapper.save(scheduleLog);
log.info("[ScheduledConfig] PeriodicTrigger ...time is {}", format.format(new Date()));
};
Trigger trigger = new AbstractTrigger(scheduleInfo) {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
log.info("[ScheduledConfig] PeriodicTrigger ...time is {}, period={}", format.format(new Date()), getScheduleInfo().getPeriod());
Date date = new PeriodicTrigger(getScheduleInfo().getPeriod(), TimeUnit.SECONDS).nextExecutionTime(triggerContext);
if (getScheduleInfo().getPeriod() < 0) {
return null;
}
return date;
}
};
addTriggerTask(scheduleInfo, new TriggerTask(task, trigger));
}
public void modifyTriggerTask(ScheduleInfo scheduleInfo) {
ScheduleInfo scheduleInfoOld = scheduledTaskMap.get(scheduleInfo.getTaskId());
if (scheduleInfoOld == null) {
log.info("[modifyTriggerTask] failed...task not exist...taskId={}", scheduleInfo.getTaskId());
return;
}
final String type = StringUtils.lowerCase(StringUtils.trimToNull(scheduleInfo.getType()));
final String typeOld = scheduleInfoOld.getType();
if (StringUtils.isBlank(type) || typeOld.equals(type)) {
if (CRON.equals(typeOld)) {
String cron = StringUtils.trimToNull(scheduleInfo.getCron());
if (StringUtils.isBlank(cron) || cron.equals(scheduleInfoOld.getCron())) {
return;
}
scheduleInfoOld.setCron(cron);
} else if (PERIOD.equals(typeOld)) {
if (scheduleInfo.getPeriod() == null || scheduleInfo.getPeriod().equals(scheduleInfoOld.getPeriod())) {
return;
}
scheduleInfoOld.setPeriod(scheduleInfo.getPeriod());
}
} else {
// 类型有变:删除就任务,创建新任务
cancelTriggerTask(scheduleInfo.getTaskId());
if (CRON.equals(type)) {
addCronTriggerTask(scheduleInfo);
} else if (PERIOD.equals(type)) {
addPeriodicTriggerTask(scheduleInfo);
}
}
}
}