Spring 整合 Quartz 時,MethodInvokingJobDetailFactoryBean (普通任務) 與 JobDetailFactoryBean (可傳參任務) 是兩種核心配置方式。本文對比其架構差異、代碼結構與適用場景,提供完整 XML 配置範本。
| 維度 | 普通任務 | 可傳參任務 |
|---|---|---|
| 調度明細 Bean | MethodInvokingJobDetailFactoryBean | JobDetailFactoryBean |
| 任務類要求 | 任意 POJO,自定義無參方法 | 必須繼承 QuartzJobBean |
| 執行入口 | 指定 targetMethod (如 work()) | 重寫 executeInternal(JobExecutionContext) |
| 參數傳遞 | 不支援 (僅無參方法) | 透過 JobDataMap 注入任意參數 |
| 靈活度 | 方法名可變,適合簡單排程 | 固定入口,適合複雜參數化業務 |
<!-- 1. 業務 Bean -->
<bean id="quartzJob" class="com.example.job.NormalJob" />
<!-- 2. 調度明細:指定目標物件與方法 -->
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="quartzJob" />
<property name="targetMethod" value="work" /> <!-- 必須無參 -->
</bean>
<!-- 3. Cron 觸發器 -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="jobDetail" />
<property name="cronExpression" value="0 0/10 * * * ?" /> <!-- 每 10 分鐘 -->
</bean>
<!-- 4. 總調度器 -->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
<property name="triggers">
<list><ref bean="cronTrigger" /></list>
</property>
</bean>
任務類:
public class NormalJob {
public void work() { System.out.println("普通任務執行..."); }
// 帶參方法會報 NoSuchMethodError,不可用
}
<!-- 1. 參數 Map -->
<bean id="jobParams" class="org.quartz.JobDataMap">
<constructor-arg>
<map>
<entry key="apiUrl" value="https://api.example.com/validate" />
<entry key="timeout" value="5000" />
</map>
</constructor-arg>
</bean>
<!-- 2. 調度明細:綁定任務類與參數 -->
<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.example.job.ParamJob" />
<property name="jobDataMap" ref="jobParams" />
</bean>
<!-- 3. 觸發器與調度器同普通任務 -->
任務類:
public class ParamJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException {
JobDataMap map = ctx.getJobDetail().getJobDataMap();
String url = map.getString("apiUrl");
int timeout = map.getIntValue("timeout");
// 業務邏輯...
}
}
@Scheduled 或 Quartz Starter 簡化配置