需求介绍
官方文档介绍:hutool官方文档
当时需求是:这个定时任务的功能是每天到点执行一些事情,并且可动态添加定时任务如果说红包到时退款,订单超时。到期自动收货等等。还可以修改执行时间。
springboot @Scheduled也是定时任务,但是他不可以动态配置
项目开始
- 引入maven依赖
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-cron</artifactId> <version>5.5.6</version> </dependency>
- 新建数据表
项目启动
- 新建一个定时任务就拿订单超时来说吧,当用户下单之后,往后推半个小时时候添加这个时间点的定时任务。
2.
添加定时任务并执行当前这个定时任务
@Override
public void addTask(CaTaskConfig task) {
log.info("成功添加定时任务:{}", task.getTitle());
CronUtil.schedule(task.getId().toString(), task.getCron(), new Task() {
@Override
public void execute() {
run(task);
}
});
}
@Override
public void run(CaTaskConfig task) {
log.info("开始执行定时任务:{},任务id:{}", task.getTitle(), task.getId());
try {
Object o = SpringBootBeanUtil.getBean( task.getClassPath());
Class t = o.getClass();
if (task.getType() != 1){
Method method = ReflectUtil.getMethod(t, "execute", CaTaskConfig.class);
method.setAccessible(true);
method.invoke(o, task);
}else{
Method method = ReflectUtil.getMethod(t, "execute", null);
method.setAccessible(true);
method.invoke(o, null);
}
} catch (Exception e) {
e.printStackTrace();
log.error("任务id:【{}】, 任务:【{}】执行失败,原因:【{}】", task.getId(), task.getTitle(), e.getCause().getMessage());
String msg = "任务id:【" + task.getId() + "】, 任务名称:【{" + task.getTitle() + "}】执行失败,原因:【{" + e.getCause().getMessage() + "}】";
CaTaskException taskException = new CaTaskException();
taskException.setTaskId(task.getId()).setMsg(msg).setCreateTime(new Date());
taskExceptionService.insert(taskException);
try {
dingdingSendMessageService.sendMessage(msg);
} catch (Exception exception) {
log.error("任务id:【{}】, 任务:【{}】钉钉发送异常,原因:【{}】", task.getId(), task.getTitle(), exception.getMessage());
}
}
}
- 在项目启动的时候先去检查有没有需要启动的定时任务实现ApplicationRunner 接口即可在项目启动完成之后执行
/**
* @description: 初始化定时任务
* @author: zsh
* @create: 2021-01-03 10:37
**/
@Slf4j
@Component
public class InitTask implements ApplicationRunner {
@Autowired
private TaskConfigService taskConfigService;
@Override
public void run(ApplicationArguments args) {
List<CaTaskConfig> taskList = taskConfigService.getAllList();
log.info("共发现定时任务有{}个", taskList.size());
if (null != taskList && taskList.size() > 0){
for (CaTaskConfig task : taskList) {
CronUtil.schedule(task.getId().toString(), task.getCron(), new Task() {
@Override
public void execute() {
taskConfigService.run(task);
}
});
}
}
CronUtil.setMatchSecond(true);
CronUtil.start();
}
}
订单超时处理类
/**
* @description:
* @author: zsh
* @create: 2021-01-22 15:26
**/
@Component(value = "cancelOrder")
@Slf4j
public class OrderJob implements Task {
@Autowired
private JdOrderService orderService;
@Autowired
private TaskConfigService taskConfigService;
@Override
public void execute(CaTaskConfig taskConfig) {
taskConfigService.removeAndStop(taskConfig.getId().toString());
log.info("开始处理超时任务,订单id{}", taskConfig.getThirdId());
orderService.cancellationOfOrderUnpaid(taskConfig.getThirdId());
}
}
主要是@Component里面value名称和通过反射去获取bean.