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

Java Web 應用任務調度最佳實踐:Quartz + Struts 插件實現標準化調度框架

     編輯:Java 相關知識

為什麼需要任務調度?

Web 應用中常見需求:定時報表生成、數據同步、郵件發送、緩存刷新… 若各開發者自行實現(Thread.sleep、Timer、甚至調用系統 cron),將導致:

  • 內存洩漏與線程失控
  • 同步/併發問題頻發
  • 不可移植(依賴 OS cron)
  • 代碼重復、難維護

Quartz 是成熟、開源、純 Java 的調度框架,支持 Cron 表達式、集群、持久化、監聽器、插件化啟動,是 Web 應用調度的標準選擇。

架構設計:Struts 插件啟動 Quartz

利用 Struts PlugIn 機制,在容器啟動時初始化 Scheduler,提供統一入口 SchedulerPlugIn.scheduleWork(JobDetail, Trigger),業務代碼無需關心啟動細節。

三步接入指南

1. web.xml 配置 Quartz Servlet(負責創建 SchedulerFactory)

<servlet>
  <servlet-name>QuartzInitializer</servlet-name>
  <servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
  <init-param>
    <param-name>shutdown-on-unload</param-name>
    <param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>start-scheduler-on-load</param-name>
    <param-value>false</param-value>  <!-- 由插件控制啟動 -->
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

2. struts-config.xml 註冊插件

<plug-in className="com.example.SchedulerPlugIn">
  <set-property property="startOnLoad" value="true" />
  <set-property property="startupDelay" value="5000" />  <!-- 延遲 5 秒啟動,等待其他初始化完成 -->
</plug-in>

3. SchedulerPlugIn 核心代碼

public class SchedulerPlugIn implements PlugIn {
    private static Scheduler scheduler;
    private String startOnLoad, startupDelay;

    public void init(ActionServlet servlet, ModuleConfig config) {
        ServletContext ctx = servlet.getServletContext();
        StdSchedulerFactory factory = (StdSchedulerFactory) 
            ctx.getAttribute(QuartzInitializerServlet.QUARTZ_FACTORY_KEY);
        try {
            scheduler = factory.getScheduler();
            if (Boolean.TRUE.toString().equals(startOnLoad)) {
                new Thread(new DelayedSchedulerStarter(scheduler, 
                    Long.parseLong(startupDelay)), "Delayed_Scheduler").start();
            }
        } catch (Exception e) { e.printStackTrace(); }
    }

    public static void scheduleWork(JobDetail job, Trigger trigger) {
        try { scheduler.scheduleJob(job, trigger); }
        catch (SchedulerException e) { e.printStackTrace(); }
    }
    // destroy() 中關閉 scheduler...
}

提交任務:業務代碼極簡

// 1. 定義觸發器:每周三 15:00
Trigger trigger = new CronTrigger("trigger1", "group1");
trigger.setCronExpression("0 0 15 ? * WED");

// 2. 定義任務詳情
JobDetail job = new JobDetail("ReportJob", "ReportGroup", 
    GenerateReportJob.class, true, true, true);

// 3. 一行代碼調度
SchedulerPlugIn.scheduleWork(job, trigger);

任務實現類

public class GenerateReportJob extends Job {
    public void execute(JobExecutionContext ctx) {
        JobDetail detail = ctx.getJobDetail();
        String jobName = detail.getName();
        JobDataMap data = detail.getJobDataMap();  // 可傳遞參數
        // 業務邏輯:查詢數據、生成 PDF、發送郵件...
        System.out.println("Report generated: " + jobName);
    }
}

常用 Trigger 快速構建

需求代碼示例
每天 02:22TriggerUtils.makeDailyTrigger(2, 22) 或 new CronTrigger(...).setCronExpression("0 22 2 * * ?")
每 5 秒TriggerUtils.makeSecondlyTrigger(5) 或 SimpleTrigger setRepeatInterval(5000)
每 24 小時SimpleTrigger setRepeatInterval(24L*60*60*1000)
工作日 09:00CronTrigger "0 0 9 ? * MON-FRI"

為什麼選 Quartz 而非 JDK 5/EE 5 內置調度?

  • Quartz API 更豐富(Cron、Calendar、JobListener、JobStore…)
  • 支持集群高可用(JDBC JobStore + 數據庫鎖)
  • 成熟社區、完善文檔、OpenSymphony 維護
  • 與 Spring、Struts、J2EE 容器無縫整合

資源鏈接

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved