在傳統 Web 應用中,若採用 TimerManager 管理定時器鏈,在類熱加載或服務器重啟時極易發生異常,導致定時任務失效或重複執行。Spring Framework 內建的 TimerFactoryBean 與 ScheduledTimerTask 提供了聲明式、可熱插拔的定時任務管理解決方案,極大簡化了開發與維護。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/schedulingContext-timer.xml</param-value>
</context-param>
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<bean id="timer" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref local="myScheduledTimerTask"/>
</list>
</property>
</bean>
<bean id="myTimerTask" class="com.example.task.MyTimerTask"></bean>
<bean id="myScheduledTimerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask"><ref bean="myTimerTask"/></property>
<property name="delay"><value>10000</value></property> <!-- 首次延遲 10 秒 -->
<property name="period"><value>86400000</value></property> <!-- 間隔 24 小時 -->
</bean>
package com.example.task;
import java.util.TimerTask;
public class MyTimerTask extends TimerTask {
@Override
public void run() {
// 這裡編寫定時執行的業務邏輯
System.out.println("定時任務執行時間:" + new java.util.Date());
}
}
scheduledTimerTasks 列表中添加多個 ScheduledTimerTask 引用即可。PropertyPlaceholderConfigurer 可將 delay/period 外置到 properties 文件,無需重啟即可修改周期。run() 方法中捕獲異常並記錄日誌,防止單個任務失敗導致整個 Timer 線程終止。Spring 的定時任務機制以「配置而非編碼」為核心,配合 IoC 容器的生命週期管理,完美解決了傳統 Timer 在熱部署、集群環境下的諸多痛點。對於更複雜的分佈式調度需求,建議進階使用 Quartz 或 Spring Boot @Scheduled。