使用 Spring-boot 的 @Scheduled 來完成一個定時任務

【Java 沒基礎】系列 Blog

使用 Spring-boot 的 @Scheduled 註解來完成定時任務

1,業務需求

a.對數據進行二次加工
b.進行離線計算
c.進行預處理任務
d.延時進行的任務,比如定時發送郵件、短信等

總之,就是將業務預先處理一部分,之後再對外服務的時候能夠提供更快、更準確的服務。

2,解決方案

a.採用 Java 基礎庫中的 java.util.Timer 類
b.採用 quartz 任務定時調度框架
c.採用 Spring-boot 核心庫中的 @Scheduled 註解

3,方案分析

a.如果我們使用 java.util.Timer 類中的 schedule() 方法,我們需要爲每個任務創建一個 timer 持續監聽系統時間,浪費 Cpu 資源。
b.採用 quartz 任務定時調度框架,在小業務量情況下,使用 quartz 也需要引入整個 quartz 框架,同時在代碼中我們需要定義一個 job,一個 trigger,和一個 scheduler 來綁定 trigger 和 job。略有繁瑣
c.採用 Spring-boot 的 @Scheduled 註解,需要定義一個被 Spring 託管的 bean,在bean中調用你需要進行的服務(Service)方法,註解中的 cron 表達式確定調用時間或者間隔。

4,確定方案

實際業務中,只有一個部分需要使用定時器,任務量少,且無需集羣操作。只需在每週二的時候對數據表進行更新操作,而項目的核心框架是 Spring-boot,所以我們確認採用 @Scheduled 來完成這個定時任務

5,具體編碼

編碼思路:
1. 我們需要一個被 Spring-boot 託管的 bean,這樣就不需要我們考慮任務的執行時間,我們可以使用 @Component 註解來完成。
2.在 bean 中定義一個方法,方法內調用已經寫好的 Serive 方法,並對返回值進行判斷,我們可以直接進行返回值處理,或者採用斷言 Assert。這個方法需要被 @Scheduled 註解,並配置 cron 表達式以控制執行時間。
3.添加日誌系統,監控定時任務的執行

開始編碼

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.jdz.configdecisionsys.service.ChangeService;

/**
 * 此項目定時任務控制器,用於數據定時加工
 * 我直接在控制器包(Controller)下定義了這個類
 * @author jdz
 */

// 將這個控制器註冊成爲一個 Bean,由 Spring 託管
@Component
public class SchedulingController {
    // 進行日誌監控
    protected Logger LOGGER = Logger.getLogger(getClass());

    @Autowired
    private ChangeService changSevice;

    /**
     * 這裏採用 cron 表達式 控制時間的方式,具體的表達式生成可以去百度Google一下,
     * 不過我可以提供一個自動生成 cron 表達式的網站:http://qqe2.com/cron/index
     * 也可以使用 fixedRate 來控制間隔時間,如:@Scheduled(fixedRate = 5000)
     * 
     * 定時執行數據加工服務,設定爲每天的凌晨2點
     * @throws Exception
     */
    @Scheduled(cron = "0 0 2 * * ?")
    // 這裏我爲了代碼篇幅節省,直接拋出異常,當然,實際項目中是對異常進行處理了的
    public void cornChangeConfigData() throws Exception { 

        // 0,清空數據表
        int clearFlag = changSevice.clearTableConfig();
        // 這裏我採用的對返回值進行處理的方式,而不是使用 assert 斷言
        if (clearFlag != 0) {
            LOGGER.error("數據表清除數據失敗");
            return;
        } else {
            LOGGER.info("加工後數據表清空");
            // 1,對單表數據進行數據加工
            int single_table = changSevice.fixSingleTableConfig();
            LOGGER.info("數據處理量  : " + single_table );
            // 2,根據加工後的單表配置數據,進行二次加工
            int total_config = changSevice.fixTotalTableConfig();
            LOGGER.info("總體配置數據數據量: " + total_config);
        }
    }
}

小結

spring-scheduled 是一個非常輕量級的定時任務工具,應用廣泛,可以支持 Timer 調度也可以支持 cron 表達式調度,使用方便快捷易懂。

點滴積累,就是進步

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章