【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 表達式調度,使用方便快捷易懂。
點滴積累,就是進步