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

自製輕量級 Timer Service:解決 EJB 2.1 不支援與整合難題

     編輯:Java 相關知識

背景動機

EJB 2.1 雖內建 TimerService,但部份應用伺服器不支援,或專案未使用 EJB 架構。為滿足定時觸發業務邏輯的需求,筆者設計了一個獨立、輕量的 TimerService 實作,無需依賴特定容器即可在 Web 應用中運行。

核心架構設計

三大核心類別

  1. TimerService:總控制器,管理排程器生命週期
  2. TimerSchedule:繼承 TimerTask,負責週期性掃描並觸發到期工作
  3. TimerJob:介面定義,規範具體排程工作需實作 execute() 與 getNextExeDate()

TimerService 關鍵程式碼

public class TimerService {
    public static final long PERIOD = 1000 * 60 * 60; // 1 小時輪詢間隔
    private Timer timer = new Timer(false);
    private TimerSchedule schedule = null;

    public void start() throws Exception {
        schedule = new TimerSchedule();
        schedule.addTimerJob(new SomeTimerJob()); // 註冊具體工作
        timer.schedule(schedule, 0, PERIOD);    // 立即啟動,每小時執行一次
    }

    public void stop() throws Exception {
        timer.cancel();
    }
}

TimerSchedule 掃描邏輯

public class TimerSchedule extends TimerTask {
    private List<TimerJob> jobs = new ArrayList<>();

    public void addTimerJob(TimerJob job) { jobs.add(job); }

    @Override
    public void run() {
        Date now = Calendar.getInstance().getTime();
        for (TimerJob job : jobs) {
            Date next = job.getNextExeDate();
            if (isTimeMatch(now, next)) {
                job.execute(); // 觸發業務邏輯
            }
        }
    }

    private boolean isTimeMatch(Date now, Date next) {
        long diff = next.getTime() - now.getTime();
        return diff >= 0 && diff <= TimerService.PERIOD; // 在一個輪詢週期內視為到期
    }
}

具體工作實作範例:每日凌點 1 點執行

public class TimerJobExample implements TimerJob {
    private Calendar nextDate;

    public TimerJobExample() {
        nextDate = Calendar.getInstance();
        nextDate.add(Calendar.DAY_OF_MONTH, 1);
        nextDate.set(Calendar.HOUR_OF_DAY, 1); // 設為隔天凌晨 1 點
    }

    @Override
    public void execute() {
        nextDate.add(Calendar.DAY_OF_MONTH, 1); // 更新下次執行時間
        nextDate.set(Calendar.HOUR_OF_DAY, 1);
        callBusinessLogic();
    }

    @Override
    public Date getNextExeDate() { return nextDate.getTime(); }

    private void callBusinessLogic() {
        System.out.println("TimerJobExample call EJB function: " + new Date());
        // 此處放入實際業務呼叫,如 EJB、Spring Bean、資料庫作業等
    }
}

Web 環境整合:透過 JSP 啟動/停止服務

<%@ page import="com.example.timer.*" %>
<%
    TimerService service = (TimerService) application.getAttribute("timerService");
    boolean isStart = true;
    if (service == null) {
        service = new TimerService();
        application.setAttribute("timerService", service);
        service.start();
    } else {
        service.stop();
        application.removeAttribute("timerService");
        isStart = false;
    }
%>
<html><body><h1><%= isStart ? "start ok" : "stop ok" %></h1></body></html>

將上述 JSP 部署於 Web 應用中,瀏覽即可切換排程服務狀態,適合測試與簡易管理介面。

適用場景與優勢

  • 無 EJB 容器或容器不支援 TimerService 的專案
  • 需輕量級、零配置的定時觸發機制
  • Spring Quartz 過於笨重、引入成本高的場合
  • 程式碼開放、易於擴充自訂 TimerJob 實作
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved