我們要達到這樣的效果
public class CancelUnpaidOrderTask implements Job { @Autowired private AppOrderService orderService; @Override public void execute(JobExecutionContext ctx) throws JobExecutionException { ... }
但是Job對象的實例化過程是在Quartz中進行的,AppOrderService是在Spring容器當中的,那么如何將他們關聯到一起呢。好在Quartz提供了JobFactory接口,讓我們可以自定義實現創建Job的邏輯。
public interface JobFactory {
Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException;
}
那么我們通過實現JobFactory 接口,在實例化Job以后,在通過ApplicationContext 將Job所需要的屬性注入即可
在Spring與Quartz集成時 用到的是org.springframework.scheduling.quartz.SchedulerFactoryBean這個類。源碼如下,我們只看最關鍵的地方。
// Get Scheduler instance from SchedulerFactory. try { this.scheduler = createScheduler(schedulerFactory, this.schedulerName); populateSchedulerContext(); if (!this.jobFactorySet && !(this.scheduler instanceof RemoteScheduler)) { // Use AdaptableJobFactory as default for a local Scheduler, unless when // explicitly given a null value through the "jobFactory" bean property. this.jobFactory = new AdaptableJobFactory(); } if (this.jobFactory != null) { if (this.jobFactory instanceof SchedulerContextAware) { ((SchedulerContextAware) this.jobFactory).setSchedulerContext(this.scheduler.getContext()); } this.scheduler.setJobFactory(this.jobFactory); } }
其中紅色標記的是重點,如果我們不指定jobFactory,那么Spring就使用AdaptableJobFactory。我們在來看一下這個類的實現
package org.springframework.scheduling.quartz; import java.lang.reflect.Method; import org.quartz.Job; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.spi.JobFactory; import org.quartz.spi.TriggerFiredBundle; import org.springframework.util.ReflectionUtils; public class AdaptableJobFactory implements JobFactory { public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException { return newJob(bundle); } public Job newJob(TriggerFiredBundle bundle) throws SchedulerException { try { Object jobObject = createJobInstance(bundle); return adaptJob(jobObject); } catch (Exception ex) { throw new SchedulerException("Job instantiation failed", ex); } } protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { // Reflectively adapting to differences between Quartz 1.x and Quartz 2.0... Method getJobDetail = bundle.getClass().getMethod("getJobDetail"); Object jobDetail = ReflectionUtils.invokeMethod(getJobDetail, bundle); Method getJobClass = jobDetail.getClass().getMethod("getJobClass"); Class jobClass = (Class) ReflectionUtils.invokeMethod(getJobClass, jobDetail); return jobClass.newInstance(); } protected Job adaptJob(Object jobObject) throws Exception { if (jobObject instanceof Job) { return (Job) jobObject; } else if (jobObject instanceof Runnable) { return new DelegatingJob((Runnable) jobObject); } else { throw new IllegalArgumentException("Unable to execute job class [" + jobObject.getClass().getName() + "]: only [org.quartz.Job] and [java.lang.Runnable] supported."); } } }
其他的我們都不管,我們就看紅色的地方,這里是創建了一個Job,那我們就在這里去給Job的屬性進行注入就可以了,讓我們寫一個類繼承它,然后復寫這個方法進行對Job的注入。
按 Ctrl+C 復制代碼
按 Ctrl+C 復制代碼
接下來把他配置到Spring當中去
<bean id="jobFactory" class="com.gary.operation.jobdemo.demo1.MyJobFactory"></bean>
然后在把org.springframework.scheduling.quartz.SchedulerFactoryBean的jobFactory設置成我們自己的。
<bean name="MyScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- 其他屬性省略 --> <property name="jobFactory" ref="jobFactory"></property> </bean>

