核心思路:兩步走
- 實現
ServletContextListener:覆寫 contextInitialized()(容器啟動時觸發)與 contextDestroyed()(容器關閉時觸發)。
- 在
contextInitialized() 中啟動定時任務:利用 java.util.Timer 的 schedule() 方法控制執行頻率。
完整代碼範例(簡訊回覆監聽原型)
1. 監聽器啟動/關閉邏輯
// ReplyListener.java
package com.hanweb.jcms;
import javax.servlet.*;
public class ReplyListener implements ServletContextListener {
private ReplyTimer rt = null;
public void contextInitialized(ServletContextEvent event) {
String status = "[SYS] SMS reply listener start.";
event.getServletContext().log(status);
System.out.println(status);
rt = new ReplyTimer(1); // 每 1 分鐘執行一次
rt.start();
}
public void contextDestroyed(ServletContextEvent event) {
String status = "[SYS] SMS reply listener stop.";
event.getServletContext().log(status);
System.out.println(status);
if (rt != null) rt.stop();
}
}
2. 定時器封裝
// ReplyTimer.java
package com.hanweb.jcms;
import java.util.*;
public class ReplyTimer {
private final Timer timer = new Timer();
private final int minutes;
public ReplyTimer(int minutes) { this.minutes = minutes; }
public void start() {
Date date = new Date(); // 立即首次執行
timer.schedule(new ReplyTask(), date, minutes * 60 * 1000);
}
public void stop() { timer.cancel(); }
}
3. 具體執行任務
// ReplyTask.java
package com.hanweb.jcms;
import java.util.*;
public class ReplyTask extends TimerTask {
public void doSomething() {
System.out.println("[SYS] SMS reply listener running");
// 實際業務邏輯:檢查簡訊、處理回覆等
}
public void run() { doSomething(); }
}
部署步驟
- 將編譯後的
.class 文件放入 WEB-INF/classes 目錄(保持包結構)。
- 在
web.xml 中註冊監聽器:
<listener>
<listener-class>com.hanweb.jcms.ReplyListener</listener-class>
</listener>
優缺點與注意事項
- 優點:零配置框架依賴,輕量級,容器管理生命週期,天然支援集群部署(每節點獨立運行)。
- 缺點:
Timer 單線程串行執行,長耗時任務會阻塞後續調度;生產環境建議升級為 ScheduledExecutorService 或引入 Quartz 等專業調度框架。
- 確保任務邏輯冪等且異常自捕獲,防止單次失敗導致調度線程終止。