转自http://www.thinksaas.cn/topics/0/679/679979.html
两者区别与作用:
普通任务:
总调度(SchedulerFactoryBean)–> 定时调度器(CronTriggerFactoryBean) –> 调度明细自定义执行方法bean(MethodInvokingJobDetailFactoryBean) –>调度bean(我们定义的job类)
可传参任务:
总调度(SchedulerFactoryBean)–> 定时调度器(CronTriggerFactoryBean) –> 调度明细bean(JobDetailFactoryBean)
如上是我们在配置调度器时的具体步骤及相互之间的依赖,区别主要在调度明细bean上,普通任务是(MethodInvokingJobDetailFactoryBean),而可传参任务是(JobDetailFactoryBean):
1)普通任务可以自定义执行方法,也就是说在其配置的调度bean(我们定义的job类)中我们可以自定义调度器最终执行的方法,可以叫work1也可以叫work2,and so on。而且要记住的一点,必须是无入参的方法!!!(做了一个测试,测试目的是看通过此类型调度类型是否也能传入参数所以定义了一个带入参的自定义方法即public void work(JobExecutionContext jobExecutionContext),最中测试结果是spring quartz会报找不到work方法及No such method work(),其默认执行我们生命的work无入参的方法。
2)可传参任务必须继承QuartzJobBean,重写protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException方法,其中JobExecutionContext就是我们在定义调度器明细时传入参数的上下文,我们可以通过JobExecutionContext取出传入的map,调度任务最终执行的就是executeInternal方法,使用该调度明细任务无法使用自定义方法。
普通任务
public class ImportCustomerScheduler {
private Logger logger = LoggerFactory.getLogger(ImportCustomerScheduler.class);
@Autowired
private CustomerErpRelationManager customerErpRelationManager;
public void execute() {
doWork();
}
private void doWork() {
logger.info(" truncate customer_erp_relation begin " + JSON.toJSONString(new Date()));
customerErpRelationManager.truncateCustomer();
logger.info(" truncate customer_erp_relation end " + JSON.toJSONString(new Date()));
logger.info(" import customer_org from erp " + JSON.toJSONString(new Date()));
try {
customerErpRelationManager.importCustomer();
} catch (Exception e) {
logger.error("doWork", e);
}
}
}
<bean id="importCustomerScheduler" class="com.yimayhd.carpool.schedule.ImportCustomerScheduler"/>
<bean id="importCustomerSchedulerBean"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="importCustomerScheduler"/>
<property name="targetMethod" value="execute"/>
<property name="concurrent" value="false"/>
</bean>
<bean id="importCustomerSchedulerCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="importCustomerSchedulerBean"/>
<property name="cronExpression" value="${scheduler.importCustomer}"/>
</bean>
<bean id="schedulerFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="importCustomerSchedulerCronTrigger"/>
</list>
</property>
</bean>
可传参任务
public class ImportTourGroupsScheduler extends QuartzJobBean {
private Logger logger = LoggerFactory.getLogger(ImportTourGroupsScheduler.class);
@Autowired
private TourGroupManager tourGroupManager;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
logger.info(" import tourGroups from erp " + JSON.toJSONString(new Date()));
try {
String bizIds = (String) context.getJobDetail().getJobDataMap().get("bizIds");
logger.info("tourGroupManager.importTourGroup========== start=============");
tourGroupManager.retryImportGroupDataWithExcep(bizIds);
logger.info("tourGroupManager.importTourGroup========== end=============");
} catch (Exception e) {
logger.error("import tourGroups from erp to carcar failed! doWork", e);
}
}
}
<bean name="context" class="org.quartz.JobDataMap">
<constructor-arg>
<map>
<entry key="bizIds" value="1">
</entry>
</map>
</constructor-arg>
</bean>
<bean id="importTourGroupsSchedulerBean" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.yimayhd.carpool.schedule.ImportTourGroupsScheduler" />
<property name="jobDataMap">
<ref bean="context"></ref>
</property>
</bean>
<bean id="importTourGroupsSchedulerCronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="importTourGroupsSchedulerBean"/>
<property name="jobDataMap">
<ref bean="context"></ref>
</property>
<property name="cronExpression" value="${scheduler.importTourGroups}"/>
</bean>
<bean id="schedulerFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="importTourGroupsSchedulerCronTrigger"/>
</list>
</property>
</bean>
需要注意的是,可传参类型的定时器类中,不能使用spring注入。因为该定时器类不是由spring管理的,而是定时器自身实例化的。
<property name="jobClass" value="com.yimayhd.carpool.schedule.ImportTourGroupsScheduler" />
public class JobDetailFactoryBean implements FactoryBean<JobDetail>, BeanNameAware, ApplicationContextAware, InitializingBean {
...
private Class<?> jobClass;
public void setJobClass(Class<?> jobClass) {
this.jobClass = jobClass;
}
public void afterPropertiesSet() {
...
JobDetailImpl jdi = new JobDetailImpl();
...
jdi.setJobClass(this.jobClass);
jdi.setJobDataMap(this.jobDataMap);
this.jobDetail = jdi;
}
...
}