承接前兩篇(頁面配置與 Cron 轉換),本文解決最後一公里:如何在應用運行期間,動態修改 Quartz Trigger 的排程時間並即時生效。核心僅需三步:獲取 Trigger → 更新 CronExpression → 重新排程。
public void updateNotificationInterval(String triggerName, String triggerId)
throws SchedulerException, ParseException {
// 1. 從 Scheduler 獲取現有 Trigger (預設群組)
CronTriggerBean trigger = (CronTriggerBean) scheduler.getTrigger(
triggerName, Scheduler.DEFAULT_GROUP);
// 2. 從 DAO 讀取最新的 Cron 表達式 (如從資料庫或配置中心)
String cronExpression = schedulerDAO.getCronExpression(triggerId);
// 3. 設置新表達式並重新排程 —— 關鍵在這一行
trigger.setCronExpression(cronExpression);
scheduler.rescheduleJob(triggerName, Scheduler.DEFAULT_GROUP, trigger);
}
rescheduleJob 會原子性地替換舊 Trigger,確保任務依照新時間執行,無需重啟應用。
為了上下文完整,補上標準的 Spring XML 配置:
<!-- 任務詳情:調用 compareService.compare() -->
<bean id="compareJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="compareService"/>
<property name="targetMethod" value="compare"/>
<property name="concurrent" value="false"/> <!-- 禁止併發 -->
</bean>
<!-- Cron Trigger -->
<bean id="compareTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="compareJob"/>
<property name="cronExpression" value="0 39 16 20 * ?"/> <!-- 初始值 -->
</bean>
<!-- Scheduler Factory -->
<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list><ref local="compareTrigger"/></list>
</property>
</bean>
JobStoreTX 將任務狀態持久化到資料庫,避免重啟丟失動態調整。scheduler.shutdown(true) 等待執行中任務完成。CronExpConversion 工具類將 UI 參數組裝為標準 Unix Cron Expression(如 0 0 12 ? * MON-FRI)。Scheduler.rescheduleJob() 熱更新 Trigger,實現零停機變更。掌握此模式,即可構建靈活的「可視化排程管理後台」,滿足業務隨時調整定時任務的需求。