文章目錄
- 🌹概述
- 🌺應用場景
- 🎄cron表達式
- 🛸入門案例
- 🎍實際應用

🌹概述
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類
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 {@Autowiredprivate OrderMapper orderMapper;//處理超時訂單的方法@Scheduled(cron = "0 * * * * ? ")//每分鐘觸發一次public void processTimeoutOrder(){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 * * ?")//每天凌晨一點觸發一次public void processDeliveryOrder(){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
根據訂單狀態和下單時間查詢訂單
這樣子我們就完成了