quartz框架实现动态添加任务——细节问题
2016-11-28 20:19
627 查看
近期,项目需要,为了实现动态添加job任务,引入quartz框架,于是开始研究quartz框架,参考文章:http://snailxr.iteye.com/blog/2076903
文章中大部分内容涉及的是有cron表达式的触发器任务,如果需要立即执行的任务,
java代码如下:
public void runAJob(DataObject dataObject) throws SchedulerException {
JobDetail jobDetail = JobBuilder.newJob(DataQuartzFactory.class)
.withIdentity(dataObject.getJobId(), dataObject.getUserId()).storeDurably().build();
jobDetail.getJobDataMap().put("key", dataObject);
scheduler.addJob(jobDetail, true);
JobKey jobKey = JobKey.jobKey(dataObject.getJobId(), dataObject.getUserId());
scheduler.triggerJob(jobKey);
scheduler.start();
}
jobdatamap中的key可以指定一个任意常量变量,dataObject即为任务类,保存了任务的所有信息,如jobid,userid等等信息,任务类可从数据库中取出,也可从队列中取出,取任务类方式自由制定。其中有一个细节问题是scheduler的注入,网上许多文章提到的xml配置为:
<bean id="schedulerFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
实际上这样的配置在正常情况下是没有问题的,但是如果你的项目中还用到了spring配置的bean,并且该bean需要在quartz的业务实现类中用到(后面会谈到),那么必须对bean做一次转换,即将spring的bean注入到quartz框架中,那么正确的配置为:
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobFactory">
<bean class="com.XXXX.JobBeanFactory"/>
</property>
</bean>
其中JobBeanFactory代码如下:
public class JobBeanFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
//把Job交给Spring来管理,这样Job就能使用由Spring产生的Bean了
applicationContext.getAutowireCapableBeanFactory().autowireBean(jobInstance);
return jobInstance;
}
}
DataQuartzFactory需要实现Job接口的execute方法,这样quartz的schedule会调度执行该方法来实现异步任务的执行, java代码如下:
public class DataQuartzFactory implements ApplicationContextAware, Job {
@Autowired
private XXService xxService;
ApplicationContext applicationContext;
public void execute(JobExecutionContext context) throws JobExecutionException {
DataObject dataObject = (DataObject) context.getMergedJobDataMap().get("key");
xxService.doTask(dataObject);
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
这里有一个非常值得注意的细节,大部分文章中都只提到需要实现Job接口,但是如果不实现ApplicationContextAware,那么xxService拿到是空指针,原理上面已经解释,不再赘述。
因此对于框架的使用,很多细节还是要掌握好,至于quartz大致原理什么的可以参考其他文章。
文章中大部分内容涉及的是有cron表达式的触发器任务,如果需要立即执行的任务,
java代码如下:
public void runAJob(DataObject dataObject) throws SchedulerException {
JobDetail jobDetail = JobBuilder.newJob(DataQuartzFactory.class)
.withIdentity(dataObject.getJobId(), dataObject.getUserId()).storeDurably().build();
jobDetail.getJobDataMap().put("key", dataObject);
scheduler.addJob(jobDetail, true);
JobKey jobKey = JobKey.jobKey(dataObject.getJobId(), dataObject.getUserId());
scheduler.triggerJob(jobKey);
scheduler.start();
}
jobdatamap中的key可以指定一个任意常量变量,dataObject即为任务类,保存了任务的所有信息,如jobid,userid等等信息,任务类可从数据库中取出,也可从队列中取出,取任务类方式自由制定。其中有一个细节问题是scheduler的注入,网上许多文章提到的xml配置为:
<bean id="schedulerFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
实际上这样的配置在正常情况下是没有问题的,但是如果你的项目中还用到了spring配置的bean,并且该bean需要在quartz的业务实现类中用到(后面会谈到),那么必须对bean做一次转换,即将spring的bean注入到quartz框架中,那么正确的配置为:
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobFactory">
<bean class="com.XXXX.JobBeanFactory"/>
</property>
</bean>
其中JobBeanFactory代码如下:
public class JobBeanFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
//把Job交给Spring来管理,这样Job就能使用由Spring产生的Bean了
applicationContext.getAutowireCapableBeanFactory().autowireBean(jobInstance);
return jobInstance;
}
}
DataQuartzFactory需要实现Job接口的execute方法,这样quartz的schedule会调度执行该方法来实现异步任务的执行, java代码如下:
public class DataQuartzFactory implements ApplicationContextAware, Job {
@Autowired
private XXService xxService;
ApplicationContext applicationContext;
public void execute(JobExecutionContext context) throws JobExecutionException {
DataObject dataObject = (DataObject) context.getMergedJobDataMap().get("key");
xxService.doTask(dataObject);
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
这里有一个非常值得注意的细节,大部分文章中都只提到需要实现Job接口,但是如果不实现ApplicationContextAware,那么xxService拿到是空指针,原理上面已经解释,不再赘述。
因此对于框架的使用,很多细节还是要掌握好,至于quartz大致原理什么的可以参考其他文章。
相关文章推荐
- Spring+Quartz实现动态添加定时任务
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- spring3整合quartz2,实现动态添加、修改、暂停、重启定时任务
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- Spring 3整合Quartz 2实现定时任务二:动态添加任务
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- Spring 3整合Quartz 2实现定时任务二:动态添加任务
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- quartz+spring 实现多任务动态定时器问题
- Spring 3整合Quartz 2实现定时任务二:动态添加任务