傳統 ServletContextListener 啟動 Timer,類別熱更新後舊 Timer 線程殘留,導致重複執行、資源洩漏。Spring 內建調度支援完美解決此問題。
<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="myScheduledTask"/>
</list>
</property>
</bean>
<bean id="myTask" class="com.example.MyTimerTask"/>
<bean id="myScheduledTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask"><ref bean="myTask"/></property>
<property name="delay"><value>10000</value></property> <!-- 首次延遲 10s -->
<property name="period"><value>86400000</value></property> <!-- 間隔 24h -->
</bean>
package com.example;
public class MyTimerTask extends TimerTask {
@Override
public void run() {
// 這裡放入定時執行的業務邏輯
System.out.println("定時任務執行:" + new Date());
}
}
@Scheduled 註解或 TaskScheduler,API 更現代化。