Spring Task 是 Spring 框架提供的一种任务调度和异步处理的解决方案。可以按照约定的时间自动执行某个代码逻辑它可以帮助开发者在 Spring 应用中轻松地实现定时任务、异步任务等功能,提高应用的效率和可维护性。
Spring Task 的主要特点包括:
信用卡每月还款提醒
银行贷款每月还款提醒
自动续费短信提醒
火车票售票系统处理未支付订单
入职纪念日为用户发送通知
下面我们来学习cron表达式,通过cron表达式可以定义任务的触发时间
cron其实就是一个字符串,可以用来定义任务触发的时间
(之前讲Linux的文章中有提到cron表达式crond的基本操作)
其实我们不用自己手写cron表达式
我们可以通过在线生成器来生成cron表达式https://cron.qqe2.com/
使用的是黑马程序员的《苍穹外卖》项目的代码来进行学习
在启动类中加上@EnableScheduling
新建一个task包和MyTask类
package com.sky.task; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.Date; @Component @Slf4j public class MyTask { //定时任务 @Scheduled(cron = "0/5 * * * * ?") public void executeTask(){ log.info("定时任务执行{}",new Date()); } }
每隔5秒触发一次
上面我们完成了SpringTask入门案例的编写,下面我们来讲解在《苍穹外卖》中的应用
我们新创建一个类OrderTask
package com.sky.task; import com.sky.entity.Orders; import com.sky.mapper.OrderMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.util.List; @Component @Slf4j public class OrderTask { @Autowired private OrderMapper orderMapper; //处理超时订单的方法 @Scheduled(cron = "0 * * * * ? ")//每分钟触发一次 public void processTimeoutOrder(){ log.info("定时处理超时订单{}", LocalDateTime.now()); //获取当前时间,并在当前时间的基础上减去 15 分钟 LocalDateTime time=LocalDateTime.now().plusMinutes(-15); ListordersList=orderMapper.getByStatusAndOrderTimeLT(Orders.PENDING_PAYMENT,time); if (ordersList!=null&&ordersList.size()>0){ for (Orders orders:ordersList){ orders.setStatus(Orders.CANCELLED); orders.setRejectionReason("订单超时,已取消"); orders.setCancelTime(LocalDateTime.now()); orderMapper.update(orders); } } } //处理一直处于派送中状态的订单 @Scheduled(cron = "0 0 1 * * ?")//每天凌晨一点触发一次 public void processDeliveryOrder(){ log.info("定时处理处于派送中的订单{}",LocalDateTime.now()); //获取当前时间,并在当前时间的基础上减去 60 分钟 LocalDateTime time=LocalDateTime.now().plusMinutes(-60); List ordersList = orderMapper.getByStatusAndOrderTimeLT(Orders.DELIVERY_IN_PROGRESS,time); if (ordersList!=null&&ordersList.size()>0){ for (Orders orders:ordersList){ orders.setStatus(Orders.CANCELLED); orderMapper.update(orders); } } } }
进入OrderMapper接口里面编写sql
根据订单状态和下单时间查询订单
这样子我们就完成了