文章目录
🌹概述
Spring Task 是 Spring 框架提供的一种任务调度和异步处理的解决方案。可以按照约定的时间自动执行某个代码逻辑它可以帮助开发者在 Spring 应用中轻松地实现定时任务、异步任务等功能,提高应用的效率和可维护性。
Spring Task 的主要特点包括:
- 简单易用:Spring Task 提供了简洁的注解和配置方式,使得任务调度和异步处理变得非常容易上手。
- 内置支持:Spring Task 内置于 Spring 框架中,无需额外的依赖,开发者可以直接在 Spring 应用中使用。
- 灵活的任务调度:Spring Task 支持基于 cron 表达式的定时任务调度,能够满足各种复杂的调度需求。
- 异步任务支持:除了定时任务,Spring Task 也支持异步任务的处理,能够在后台线程中执行耗时操作,提高系统的响应速度。
- 集成注解:Spring Task 提供了 @Scheduled 注解用于标识定时任务的方法,以及 @Async 注解用于标识异步任务的方法,使用起来非常方便。
- 监控和管理:Spring Task 支持任务的监控和管理,可以通过 JMX 或者 Spring Boot Actuator 进行任务的查看和控制。
🌺应用场景
- 信用卡每月还款提醒
- 银行贷款每月还款提醒
- 自动续费短信提醒
- 火车票售票系统处理未支付订单
- 入职纪念日为用户发送通知
下面我们来学习cron表达式,通过cron表达式可以定义任务的触发时间
🎄cron表达式
cron其实就是一个字符串,可以用来定义任务触发的时间
(之前讲Linux的文章中有提到cron表达式crond的基本操作)
其实我们不用自己手写cron表达式
我们可以通过在线生成器来生成cron表达式
https://cron.qqe2.com/
🛸入门案例
使用的是黑马程序员的《苍穹外卖》项目的代码来进行学习
在启动类中加上
@EnableScheduling
新建一个task包和MyTask类
packagecom.sky.task;importlombok.extern.slf4j.Slf4j;importorg.springframework.scheduling.annotation.Scheduled;importorg.springframework.stereotype.Component;importjava.util.Date;@Component@Slf4jpublicclassMyTask{//定时任务@Scheduled(cron ="0/5 * * * * ?")publicvoidexecuteTask(){
log.info("定时任务执行{}",newDate());}}
每隔5秒触发一次
上面我们完成了SpringTask入门案例的编写,下面我们来讲解在《苍穹外卖》中的应用
🎍实际应用
我们新创建一个类OrderTask
packagecom.sky.task;importcom.sky.entity.Orders;importcom.sky.mapper.OrderMapper;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.scheduling.annotation.Scheduled;importorg.springframework.stereotype.Component;importjava.time.LocalDateTime;importjava.util.List;@Component@Slf4jpublicclassOrderTask{@AutowiredprivateOrderMapper orderMapper;//处理超时订单的方法@Scheduled(cron ="0 * * * * ? ")//每分钟触发一次publicvoidprocessTimeoutOrder(){
log.info("定时处理超时订单{}",LocalDateTime.now());//获取当前时间,并在当前时间的基础上减去 15 分钟LocalDateTime time=LocalDateTime.now().plusMinutes(-15);List<Orders> ordersList=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 * * ?")//每天凌晨一点触发一次publicvoidprocessDeliveryOrder(){
log.info("定时处理处于派送中的订单{}",LocalDateTime.now());//获取当前时间,并在当前时间的基础上减去 60 分钟LocalDateTime time=LocalDateTime.now().plusMinutes(-60);List<Orders>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
根据订单状态和下单时间查询订单
这样子我们就完成了
版权归原作者 在下小吉. 所有, 如有侵权,请联系我们删除。