背景
在公司做项目的时候碰到一个需求,要求为可以自定义配置动态任务的开始时间,由于一开始只想到使用@Schedule来进行,但显然不满足需求,为此,询问同事后得知有一种可以自定义定时任务的用法,遂记录一波
定时任务的管理类
@Component
public class ComfirmManager{
@Autowired
private TaskScheduler threadPoolTaskScheduler;
private static Map<String,ScheduledFuture<?>> scheduledFutureMap = new HashMap<>(16);
/**
* 增加定时任务
*/
public void addConfirm() {
StringBuilder cronOrderL = new StringBuilder();
StringBuilder cronOrderD = new StringBuilder();
//这个步骤是为了取数据库存放的定时任务的启动时间,格式为时分秒
Dict orderLconfirmedTime = dictService.getOne(new LambdaQueryWrapper<Dict>().eq(Dict::getCode, "ORDER_LCONFIRMED_TIME"));
Dict orderDconfirmedTime = dictService.getOne(new LambdaQueryWrapper<Dict>().eq(Dict::getCode, "ORDER_DCONFIRMED_TIME"));
String[] splitOrderD = orderDconfirmedTime.getVal().split(":");
String[] splitOrderL = orderLconfirmedTime.getVal().split(":");
//拼接cron表达式并设置定时任务到系统当中
cronOrderL.append(splitOrderL[2]).append(" ").append(splitOrderL[1]).append(" ").append(splitOrderL[0]).append(" * * ? ");
cronOrderD.append(splitOrderD[2]).append(" ").append(splitOrderD[1]).append(" ").append(splitOrderD[0]).append(" * * ? ");
ScheduledFuture<?> scheduleOrderL = threadPoolTaskScheduler.schedule(new OrderLunchRunnable(), triggerContext -> new CronTrigger(cronOrderL.toString()).nextExecutionTime(triggerContext));
ScheduledFuture<?> scheduleOrderD = threadPoolTaskScheduler.schedule(new OrderDinnerRunnable(), triggerContext -> new CronTrigger(cronOrderD.toString()).nextExecutionTime(triggerContext));
scheduledFutureMap.put("scheduleOrderL",scheduleOrderL);
scheduledFutureMap.put("scheduleOrderD",scheduleOrderD);
}
/**
* 删除定时任务
*/
public void deleteConfirm() {
for (Map.Entry<String, ScheduledFuture<?>> entry : scheduledFutureMap.entrySet()) {
entry.getValue().cancel(true);
}
}
}
两个定时任务实现代码
public class OrderLunchRunnable implements Runnable{
private DictMapper dictMapper = ManageSpringBeans.getBean(DictMapper.class);
private OrderMapper orderMapper = ManageSpringBeans.getBean(OrderMapper.class);
@Override
public void run() {
System.out.println("执行相关定时任务");
}
}
public class OrderDinnerRunnable implements Runnable{
private DictMapper dictMapper = ManageSpringBeans.getBean(DictMapper.class);
private OrderMapper orderMapper = ManageSpringBeans.getBean(OrderMapper.class);
@Override
public void run() {
System.out.println("执行相关定时任务");
}
}
注意点:因为类继承了Runnable,是没有办法直接使用@Autowired去获取相关的bean,所以这个时候需要写一个ManageSpringBeans工具类来替代注解去获得相关的bean
@Component
public class ManageSpringBeans implements ApplicationContextAware {
private static ApplicationContext context;
public static <T> T getBean(final Class<T> requiredType) {
return context.getBean(requiredType);
}
public static <T> T getBean(final String beanName) {
@SuppressWarnings("unchecked")
final T bean = (T) context.getBean(beanName);
return bean;
}
public static <T> Map<String, T> getBeans(final Class<T> requiredType) {
return context.getBeansOfType(requiredType);
}
public static Map<String, Object> getBeansWithAnnotation(final Class<? extends Annotation> annotationType) {
return context.getBeansWithAnnotation(annotationType);
}
@Override
public void setApplicationContext(final ApplicationContext applicationContext) {
context = applicationContext;
}
}