首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring 定時任務 @Scheduled 完整配置指南與常見坑點

     編輯:Java 綜合教學

啟用排程支援

在 Spring XML 配置檔引入 task 命名空間並啟用註解驅動:

<beans xmlns:task="https://www.springframework.org/schema/task"
       xsi:schemaLocation="...
       https://www.springframework.org/schema/task/spring-task-4.0.xsd">

    <task:annotation-driven />
</beans>

編寫排程元件

@Component
public class DailyPiracyJob {
    private static final Logger log = LoggerFactory.getLogger(DailyPiracyJob.class);

    @Autowired
    private AppInfoService appInfoService;

    @Scheduled(cron = "0 0 23 * * ?")  // 每天 23:00 執行
    public void scan() {
        try {
            List<AppInfo> list = appInfoService.selectAllAppInfo();
            if (list != null && !list.isEmpty()) {
                for (AppInfo app : list) {
                    appInfoService.insertDailyPiracy(app.getAppMd5());
                }
            }
        } catch (Exception e) {
            log.error("Channel Monitoring failed", e);
        }
    }
}

關鍵註解說明

  • @Component:納入元件掃描,讓 Spring 管理 Bean 生命週期。
  • @Scheduled(cron="..."):Core 註解,方法必須 void 無參數;Cron 運算式參考 Quartz 格式。

常見坑點:default-lazy-init="true" 會導致 @Scheduled 失效

若在 <beans default-lazy-init="true"> 下,所有 Bean 延遲初始化,排程註解解析器無法及早掃描到 Bean,導致任務不執行。解決:移除該屬性,或對排程類別單獨設定 lazy-init="false"。

進階:固定頻率 vs 固定延遲

@Scheduled(fixedRate = 5000)      // 上次開始後 5 秒再啟動(併發風險)
@Scheduled(fixedDelay = 5000)     // 上次結束後 5 秒再啟動(串行安全)
@Scheduled(initialDelay = 1000, fixedRate = 5000) // 首次延遲 1 秒

生產環境建議

  • 搭配 @Async 將長耗時任務放入執行緒池,避免阻塞排程執行緒。
  • 使用 TaskScheduler 自訂執行緒池大小:@Bean public TaskScheduler scheduler() { return new ThreadPoolTaskScheduler(); }
  • 分散式環境考慮加入分散式鎖(如 ShedLock、Quartz Cluster)防止重複執行。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved