启动类添加注解 @EnableScheduling 开启任务调度
自定义定时任务类
cron表达式其实就是一个字符串,通过cron表达式可以定义任务触发的时间
构成规则:分为6或7个域,由空格分隔开,每个域代表一个含义
每个域的含义分别为:秒、分钟、小时、日、月、周、年(可选)
以我的项目为例,我的项目是一个类似美团的外卖平台
@Slf4j
@Component
public class OrderTask {
@Autowired
private OrderService orderService;
/**
* 扫描超过15分钟未支付的订单,并取消。
*
* */
//@Scheduled(cron="*/5 * * * * ?")
public void handleUnpayOrder(){
log.info("扫描超过15分钟未支付的订单任务启动。。。。");
// 分页查询系统中所有未支付的订单
List<Orders> list = orderService.getUnpayOrders();
if(CollectionUtils.isEmpty(list)){
log.info("没有未支付的订单");
return;
}
// 判断下单时间和 当前时间 的差
for (Orders orders : list) {
// 下单时间
LocalDateTime orderTime = orders.getOrderTime();
// 当前时间
LocalDateTime now = LocalDateTime.now();
// 如果没有超过15分钟,不管
boolean expired = now.minusMinutes(15).isAfter(orderTime);
if(!expired){
continue;
}
// 如果超过15,修改成取消状态
orderService.cancel(orders.getId(), "用户超时未支付");
}
}
/**
* 处理下单超过1小时仍然处于派送中的订单,改成已完成
* 每隔1分钟处理一次
* */
// @Scheduled(cron = "8 */1 * * * ?")
public void handleDeliveryOrder(){
log.info("处理下单超过1小时仍然处于派送中的订单任务启动。。。。");
// 先计算1小时之前这个时间
LocalDateTime oneHourBefore = LocalDateTime.now().minusHours(1);
// 分页查询,防止数据太多导致内存溢出,(1)下单时间是1小时之前 (2)status = 派送中
int page = 1;
int pageSize = 2;
while(true){
log.info("查询第{}页", page);
List<Orders> order = orderService.getByStatusAndOrderTimeBefore(Orders.DELIVERY_IN_PROGRESS, oneHourBefore, 1, pageSize);
// 说明已经没有更多的数据
if(CollectionUtils.isEmpty(order)){
log.info("没有更多数据,结束");
break;
}
// 如果有数据,修改状态为已经完成
for (Orders orders : order) {
orderService.complete(orders.getId());
}
// 如果当前页的记录条数 < 分页的大小,说明没有下一页数据
if(order.size() < pageSize){
break;
}
page++;
}
}