您的位置:首页 > 编程语言 > Java开发

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大致原理什么的可以参考其他文章。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息