最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Scheduler定時(shí)任務(wù)實(shí)戰(zhàn)指南(零基礎(chǔ)入門任務(wù)調(diào)度)

 更新時(shí)間:2025年09月10日 15:03:18   作者:冬日下祈安  
本文介紹SpringScheduler在電商訂單超時(shí)處理中的應(yīng)用,涵蓋啟用定時(shí)任務(wù)、使用@Scheduled注解、cron表達(dá)式配置、線程池優(yōu)化及異步執(zhí)行等核心內(nèi)容,本文給大家介紹Spring Scheduler定時(shí)任務(wù)實(shí)戰(zhàn)指南,感興趣的朋友跟隨小編一起看看吧

前言

在日常開發(fā)中,我們經(jīng)常需要處理定時(shí)任務(wù):每天凌晨的數(shù)據(jù)同步、每小時(shí)的統(tǒng)計(jì)報(bào)表、每5分鐘的狀態(tài)檢查等。Spring框架提供了一個(gè)簡(jiǎn)單而強(qiáng)大的定時(shí)任務(wù)框架——Spring Scheduler,讓我們能夠以聲明的方式輕松實(shí)現(xiàn)各種定時(shí)任務(wù)需求。

本文將通過一個(gè)真實(shí)案例,帶你從入門到掌握Spring Scheduler的使用。

一、Spring Scheduler簡(jiǎn)介

Spring Scheduler是Spring框架提供的定時(shí)任務(wù)調(diào)度器,它基于注解和配置的方式,讓任務(wù)調(diào)度變得簡(jiǎn)單直觀。主要特點(diǎn)包括:

  • 支持cron表達(dá)式、固定延遲、固定頻率等多種調(diào)度方式
  • 與Spring容器無縫集成,可直接使用Spring管理的Bean
  • 支持異步執(zhí)行和線程池配置
  • 無需額外依賴,Spring Boot中開箱即用

二、項(xiàng)目場(chǎng)景:電商訂單超時(shí)處理

假設(shè)我們有一個(gè)電商系統(tǒng),需要處理訂單超時(shí)自動(dòng)關(guān)閉的功能:訂單創(chuàng)建后30分鐘內(nèi)未支付,系統(tǒng)自動(dòng)將其標(biāo)記為已關(guān)閉。

環(huán)境準(zhǔn)備

在Spring Boot項(xiàng)目中,首先確保添加了基礎(chǔ)依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Spring Scheduler已經(jīng)在Spring Boot的web starter中包含,無需額外添加依賴。

啟用定時(shí)任務(wù)

在Spring Boot主類或配置類上添加@EnableScheduling注解:

@SpringBootApplication
@EnableScheduling
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

三、實(shí)現(xiàn)訂單超時(shí)檢查任務(wù)

1. 創(chuàng)建訂單服務(wù)

首先創(chuàng)建一個(gè)訂單服務(wù)類,包含基本的訂單處理方法:

@Service
public class OrderService {
    private static final Logger logger = LoggerFactory.getLogger(OrderService.class);
    // 模擬訂單存儲(chǔ)
    private Map<Long, Order> orderMap = new ConcurrentHashMap<>();
    private AtomicLong idGenerator = new AtomicLong(0);
    /**
     * 創(chuàng)建新訂單
     */
    public Order createOrder(Order order) {
        Long orderId = idGenerator.incrementAndGet();
        order.setId(orderId);
        order.setCreateTime(new Date());
        order.setStatus(OrderStatus.CREATED);
        orderMap.put(orderId, order);
        logger.info("創(chuàng)建訂單成功,訂單ID: {}", orderId);
        return order;
    }
    /**
     * 檢查并處理超時(shí)訂單
     */
    public void checkAndCloseTimeoutOrders() {
        Date now = new Date();
        int timeoutMinutes = 30;
        for (Order order : orderMap.values()) {
            if (OrderStatus.CREATED.equals(order.getStatus())) {
                long diffInMillis = now.getTime() - order.getCreateTime().getTime();
                long diffInMinutes = diffInMillis / (1000 * 60);
                if (diffInMinutes >= timeoutMinutes) {
                    order.setStatus(OrderStatus.CLOSED);
                    order.setCloseTime(now);
                    logger.info("訂單超時(shí)已關(guān)閉,訂單ID: {}", order.getId());
                }
            }
        }
    }
    /**
     * 獲取訂單狀態(tài)
     */
    public OrderStatus getOrderStatus(Long orderId) {
        Order order = orderMap.get(orderId);
        return order != null ? order.getStatus() : null;
    }
}
/**
 * 訂單狀態(tài)枚舉
 */
public enum OrderStatus {
    CREATED,     // 已創(chuàng)建
    PAID,        // 已支付
    CLOSED       // 已關(guān)閉
}
/**
 * 訂單實(shí)體類
 */
public class Order {
    private Long id;
    private String productName;
    private BigDecimal amount;
    private Date createTime;
    private Date closeTime;
    private OrderStatus status;
    // 省略getter和setter方法
}

2. 實(shí)現(xiàn)定時(shí)任務(wù)

現(xiàn)在創(chuàng)建定時(shí)任務(wù)類,定期檢查超時(shí)訂單:

@Component
public class OrderTimeoutScheduler {
    private static final Logger logger = LoggerFactory.getLogger(OrderTimeoutScheduler.class);
    @Autowired
    private OrderService orderService;
    /**
     * 每5分鐘檢查一次超時(shí)訂單
     * 使用cron表達(dá)式:每5分鐘執(zhí)行一次
     */
    @Scheduled(cron = "0 */5 * * * ?")
    public void checkOrderTimeout() {
        logger.info("開始執(zhí)行訂單超時(shí)檢查任務(wù)...");
        long startTime = System.currentTimeMillis();
        try {
            orderService.checkAndCloseTimeoutOrders();
        } catch (Exception e) {
            logger.error("訂單超時(shí)檢查任務(wù)執(zhí)行失敗", e);
        }
        long endTime = System.currentTimeMillis();
        logger.info("訂單超時(shí)檢查任務(wù)執(zhí)行完成,耗時(shí):{}ms", (endTime - startTime));
    }
    /**
     * 另一種方式:固定延遲執(zhí)行
     * 上一次任務(wù)執(zhí)行完成后,延遲5分鐘再執(zhí)行
     */
    // @Scheduled(fixedDelay = 5 * 60 * 1000)
    // public void checkOrderTimeoutWithFixedDelay() {
    //     // 實(shí)現(xiàn)邏輯
    // }
    /**
     * 固定頻率執(zhí)行
     * 每5分鐘執(zhí)行一次,無論上一次任務(wù)是否完成
     */
    // @Scheduled(fixedRate = 5 * 60 * 1000)
    // public void checkOrderTimeoutWithFixedRate() {
    //     // 實(shí)現(xiàn)邏輯
    // }
}

3. 測(cè)試定時(shí)任務(wù)

創(chuàng)建一個(gè)測(cè)試控制器來驗(yàn)證我們的定時(shí)任務(wù):

@RestController
@RequestMapping("/orders")
public class OrderController {
    @Autowired
    private OrderService orderService;
    @PostMapping
    public ResponseEntity<Order> createOrder(@RequestBody Order order) {
        Order createdOrder = orderService.createOrder(order);
        return ResponseEntity.ok(createdOrder);
    }
    @GetMapping("/{orderId}/status")
    public ResponseEntity<OrderStatus> getOrderStatus(@PathVariable Long orderId) {
        OrderStatus status = orderService.getOrderStatus(orderId);
        return status != null ? 
            ResponseEntity.ok(status) : 
            ResponseEntity.notFound().build();
    }
}

啟動(dòng)應(yīng)用后,你可以:

  1. 通過POST /orders 創(chuàng)建訂單
  2. 等待5分鐘,查看日志中定時(shí)任務(wù)的執(zhí)行情況
  3. 30分鐘后,通過GET /orders/{id}/status 檢查訂單狀態(tài)是否變?yōu)镃LOSED

四、cron表達(dá)式詳解

Spring Scheduler支持標(biāo)準(zhǔn)的cron表達(dá)式,由6個(gè)字段組成(Spring支持7個(gè)字段,包含秒):

秒 分 時(shí) 日 月 周 年(可選)

常用cron表達(dá)式示例:

  • 0 * * * * ?:每分鐘執(zhí)行一次
  • 0 */5 * * * ?:每5分鐘執(zhí)行一次
  • 0 0 * * * ?:每小時(shí)執(zhí)行一次
  • 0 0 0 * * ?:每天凌晨執(zhí)行
  • 0 0 12 * * ?:每天中午12點(diǎn)執(zhí)行
  • 0 0 10,14,16 * * ?:每天10點(diǎn)、14點(diǎn)、16點(diǎn)執(zhí)行

五、高級(jí)配置:線程池與異步執(zhí)行

默認(rèn)情況下,Spring Scheduler使用單線程執(zhí)行所有定時(shí)任務(wù)。如果任務(wù)較多或執(zhí)行時(shí)間較長(zhǎng),可能需要配置線程池:

@Configuration
public class SchedulerConfig {
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(10); // 線程池大小
        scheduler.setThreadNamePrefix("scheduled-task-");
        scheduler.setAwaitTerminationSeconds(60);
        scheduler.setWaitForTasksToCompleteOnShutdown(true);
        return scheduler;
    }
}

對(duì)于需要異步執(zhí)行的任務(wù),可以結(jié)合@Async注解使用:

@Async
@Scheduled(fixedRate = 5000)
public void asyncScheduledTask() {
    // 這個(gè)任務(wù)會(huì)在單獨(dú)的線程中異步執(zhí)行
}

確保在配置類上添加@EnableAsync注解。

六、最佳實(shí)踐與注意事項(xiàng)

  1. ??任務(wù)冪等性??:確保定時(shí)任務(wù)可以多次執(zhí)行而不會(huì)產(chǎn)生副作用
  2. ??異常處理??:在任務(wù)內(nèi)部妥善處理異常,避免影響其他任務(wù)執(zhí)行
  3. ??分布式環(huán)境??:在集群部署時(shí),需要考慮使用分布式鎖或只在一臺(tái)實(shí)例上執(zhí)行
  4. ??避免長(zhǎng)時(shí)間執(zhí)行??:長(zhǎng)時(shí)間運(yùn)行的任務(wù)會(huì)影響其他定時(shí)任務(wù)的執(zhí)行
  5. ??配置化??:將cron表達(dá)式放在配置文件中,便于不同環(huán)境調(diào)整
# application.properties
order.timeout.cron=0 */5 * * * ?
@Scheduled(cron = "${order.timeout.cron}")
public void checkOrderTimeout() {
    // ...
}

七、總結(jié)

Spring Scheduler提供了簡(jiǎn)單而強(qiáng)大的定時(shí)任務(wù)功能,通過本文的電商訂單超時(shí)處理案例,我們可以看到:

  1. 使用@EnableScheduling啟用定時(shí)任務(wù)支持
  2. 通過@Scheduled注解聲明定時(shí)方法,支持cron表達(dá)式、固定延遲和固定頻率
  3. 定時(shí)任務(wù)方法可以是任何Spring管理的Bean的方法
  4. 可以通過配置線程池來優(yōu)化任務(wù)執(zhí)行性能
  5. 結(jié)合@Async可以實(shí)現(xiàn)異步定時(shí)任務(wù)

Spring Scheduler雖然功能強(qiáng)大,但在分布式環(huán)境中需要注意任務(wù)重復(fù)執(zhí)行的問題。對(duì)于復(fù)雜的分布式調(diào)度需求,可以考慮使用Quartz或XXL-Job等專業(yè)調(diào)度框架。

希望本文能幫助你理解和掌握Spring Scheduler的使用,為你的項(xiàng)目開發(fā)提供便利。

到此這篇關(guān)于Spring Scheduler定時(shí)任務(wù)實(shí)戰(zhàn):從零掌握任務(wù)調(diào)度的文章就介紹到這了,更多相關(guān)Spring Scheduler定時(shí)任務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java幾個(gè)實(shí)例帶你進(jìn)階升華上篇

    Java幾個(gè)實(shí)例帶你進(jìn)階升華上篇

    與其明天開始,不如現(xiàn)在行動(dòng),本文為你帶來幾個(gè)Java書寫的實(shí)際案例,對(duì)鞏固編程的基礎(chǔ)能力很有幫助,快來一起往下看看吧
    2022-03-03
  • SpringMVC?RESTFul實(shí)體類創(chuàng)建及環(huán)境搭建

    SpringMVC?RESTFul實(shí)體類創(chuàng)建及環(huán)境搭建

    這篇文章主要為大家介紹了SpringMVC?RESTFul實(shí)體類創(chuàng)建及環(huán)境搭建詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • SpringSecurity入門實(shí)戰(zhàn)應(yīng)用場(chǎng)景

    SpringSecurity入門實(shí)戰(zhàn)應(yīng)用場(chǎng)景

    本文總結(jié)了基于SpringSecurity的數(shù)據(jù)庫(kù)登錄認(rèn)證實(shí)戰(zhàn),包括創(chuàng)建數(shù)據(jù)庫(kù)表、實(shí)體類、DBUserDetailsManager、配置、密碼加密、添加用戶、自定義SecurityUser、前后端響應(yīng)處理、配置handler、跨域解決、身份認(rèn)證概念解析及會(huì)話并發(fā)處理等內(nèi)容,感興趣的朋友一起看看吧
    2026-04-04
  • java類的全限定名是什么

    java類的全限定名是什么

    Java中的全限定名指的是包含包名和類名的完整標(biāo)識(shí),例如“java.lang.String”,而非限定名僅指類名,如“String”,全限定名用于區(qū)分不同包中相同名字的類,避免引用混淆,特別是在有多個(gè)包含相同類名的庫(kù)時(shí)
    2024-09-09
  • java讀取圖片并顯示方式

    java讀取圖片并顯示方式

    這篇文章主要介紹了java讀取圖片并顯示方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • SpringBoot中的yaml語法及靜態(tài)資源訪問問題

    SpringBoot中的yaml語法及靜態(tài)資源訪問問題

    這篇文章主要介紹了SpringBoot中的yaml語法及靜態(tài)資源訪問問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • Java獲取網(wǎng)絡(luò)文件并插入數(shù)據(jù)庫(kù)的代碼

    Java獲取網(wǎng)絡(luò)文件并插入數(shù)據(jù)庫(kù)的代碼

    抓取各大網(wǎng)站的數(shù)據(jù)插入數(shù)據(jù)庫(kù),這樣就不用為沒有數(shù)據(jù)而煩惱了
    2010-06-06
  • Java并發(fā)系列之CyclicBarrier源碼分析

    Java并發(fā)系列之CyclicBarrier源碼分析

    這篇文章主要為大家詳細(xì)分析了Java并發(fā)系列之CyclicBarrier源碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • MyBatis的SQL執(zhí)行結(jié)果和客戶端執(zhí)行結(jié)果不一致問題排查

    MyBatis的SQL執(zhí)行結(jié)果和客戶端執(zhí)行結(jié)果不一致問題排查

    本文主要介紹了MyBatis的SQL執(zhí)行結(jié)果和客戶端執(zhí)行結(jié)果不一致問題排查,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 詳解Spring Cloud Zuul 服務(wù)網(wǎng)關(guān)

    詳解Spring Cloud Zuul 服務(wù)網(wǎng)關(guān)

    本篇文章主要介紹了詳解Spring Cloud Zuul 服務(wù)網(wǎng)關(guān),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-12-12

最新評(píng)論

上林县| 郓城县| 固阳县| 抚远县| 岳普湖县| 岱山县| 嵩明县| 南昌市| 乐昌市| 三亚市| 台湾省| 合江县| 新安县| 锡林郭勒盟| 同仁县| 海城市| 高陵县| 墨竹工卡县| 六安市| 遂平县| 曲阜市| 大关县| 北流市| 平潭县| 无为县| 宽城| 霍州市| 昂仁县| 屯留县| 巴青县| 梓潼县| 托克托县| 马公市| 栖霞市| 搜索| 蒙阴县| 哈尔滨市| 潼关县| 永昌县| 富阳市| 永春县|