Spring 3 引入了基於註解的任務調度支持,僅需兩步即可輕鬆構建定時任務:編寫任務類標註 @Scheduled,並在 XML 中啟用任務命名空間。本文將通過完整示例,詳細講解三種觸發模式(固定延遲、固定頻率、Cron 表達式)的區別與配置細節。
@Scheduled 註解。task 命名空間,聲明執行器、調度器並啟用註解驅動。package com.zywang.spring.task;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class SpringTaskDemo {
// fixedDelay: 上一次執行結束後 5 秒再執行
@Scheduled(fixedDelay = 5000)
public void doSomethingWithDelay() {
System.out.println("I'm doing with delay now! " + new java.util.Date());
}
// fixedRate: 無視執行時長,每 5 秒觸發一次
@Scheduled(fixedRate = 5000)
public void doSomethingWithRate() {
System.out.println("I'm doing with rate now! " + new java.util.Date());
}
// cron: 每分鐘第 0,5,10... 秒觸發 (每 5 秒)
@Scheduled(cron = "0/5 * * * * *")
public void doSomethingWithCron() {
System.out.println("I'm doing with cron now! " + new java.util.Date());
}
}
| 屬性 | 觸發邏輯 | 適用場景 | 並發風險 |
|---|---|---|---|
fixedDelay | 上次執行結束 → 等待指定時間 → 下次執行 | 任務耗時不固定,需保證間隔 | 低 (串行) |
fixedRate | 固定時間間隔觸發,若上次未結束則並發執行 | 固定頻率采集、心跳上報 | 高 (需線程池) |
cron | 基於 Cron 表達式精確時間點觸發 | 定時備份、報表生成等業務定時 | 中 (取決於執行時長) |
Cron 表達式結構 (6 域): 秒 分 時 日 月 周
0/5 * * * * *:每分鐘第 0、5、10... 秒 (每 5 秒)0 0 2 * * ?:每天凌晨 2 點整0 0/30 9-17 * * MON-FRI:工作日 9-17 點每半小時<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:task="https://www.springframework.org/schema/task"
xsi:schemaLocation="
https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/task https://www.springframework.org/schema/task/spring-task-3.0.xsd">
<!-- 線程池執行器:用於 @Scheduled 方法的實際運行線程 -->
<task:executor id="executor" pool-size="5" />
<!-- 調度器:負責按時觸發任務,pool-size 應 >= 並發任務數 -->
<task:scheduler id="scheduler" pool-size="10" />
<!-- 啟用 @Scheduled 註解驅動,關聯執行器與調度器 -->
<task:annotation-driven executor="executor" scheduler="scheduler" />
</beans>
task:executor:定義執行任務的線程池,pool-size 控制最大並發數。task:scheduler:定義調度線程池,負責按時提交任務到執行器。task:annotation-driven:掃描 @Scheduled 註解,將任務註冊到調度器。@Component 或在 XML 定義 <bean>),否則註解不生效。try-catch 並記錄日誌,或實現 ErrorHandler 接口統一處理。@Scheduled 註解屬性為常量,無法運行時修改。需動態調度請使用 TaskScheduler API 編程式註冊 Runnable。task:scheduler 指定 timezone 屬性或配置 Trigger 實現。本示例基於 Spring 3.0.5 驗證。Spring 4+ 繼續支持此配置,但推薦遷移至 Java Config (@EnableScheduling + @Configuration) 以獲得類型安全與 IDE 支持。