我正在使用spring mvc 4.2.5.RELEASE和quartz 2.2.1 quartz-jobs 2.2.1
当用户输入石英作业的名称和cron表达式时,我有一个用户界面,然后我创建这样的作业
SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
schedFact.getScheduler().getContext().put("externalInstanceEstatus", myObject);
Scheduler sched = schedFact.getScheduler();
sched.start();
JobDetail job = null;
job = newJob(MyTask.class)
.withIdentity((String) String.valueOf(myUniqueId), "group1")
.build();
Trigger triggerCron = TriggerBuilder
.newTrigger()
.withIdentity(String.valueOf(myUniqueId), "group1")
.withSchedule(
CronScheduleBuilder.cronSchedule(myObject.getExpresionCron()))
.build();
sched.scheduleJob(job, triggerCron);
每次用户进入该界面时,他都可以创建一个工作,这很好 但是当我关闭服务器时,我的所有工作都丢失了。我通过在数据库中保存作业名称和cron表达式解决了这个问题,我创建了一个方法,从该表中获取所有记录,然后重新创建这样的作业
public void reCreateJobs() {
ArrayList<MyJob> listOfJobs = searchAllJobsInDB();
SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
Scheduler sched = schedFact.getScheduler();
//I loop the lsit and I delete all the jobs in the scheduler just in case
for (MyJob myJob : listOfJobs) {
for (String group : sched.getJobGroupNames()) {
for (JobKey jobKey : sched.getJobKeys((GroupMatcher<JobKey>) groupEquals(group))) {
if (jobKey.getName().equals(String.valueOf(myJob.getIdMyJob()))) {
sched.deleteJob(jobKey);
}
}
}
}
sched.start();
//THIS IS WHERE I CREATE ALL THE JOBS AGAIN
for (MyJob myJob : listOfJobs) {
JobDetail job = newJob(TareaImprimir.class)
.withIdentity((String) String.valueOf(myJob.getIdMyJob()), "group1")
.build();
JobDetail job = null;
Trigger triggerCron = TriggerBuilder
.newTrigger()
.withIdentity(String.valueOf(myJob.getIdMyJob()), "group1")
.withSchedule(
CronScheduleBuilder.cronSchedule(myJob.getExpresionCron()))
.build();
sched.scheduleJob(job, triggerCron);
}
}
这也很好我可以再次创建作业,它们运行良好,
我的问题是我需要将值传递给Task Class而我不知道如何传递它,我知道如何在第一次创建作业时传递它
schedFact.getScheduler().getContext().put("externalInstance", myObject);
然后我在我的任务类中得到它
SchedulerContext schedulerContext = null;
try {
schedulerContext = context.getScheduler().getContext();
} catch (SchedulerException ex) {
ex.printStackTrace();
}
MyObject externalInstance
= (MyObject) schedulerContext.get("externalInstance");
我的问题是,当我在我的方法reCreateJobs()
中重新创建作业时,我不知道如何执行此操作,我从DataBase中获取它们
如何为每个Job在我的方法reCreateJobs()
中设置该externalInstance,或者如何将该值传递给该循环内的MyTask类
这是我的任务类
public class MyTask implements Job {
@Autowired
SomeDAO someDAO;
public void execute(JobExecutionContext context)
throws JobExecutionException {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
SchedulerContext schedulerContext = null;
try {
schedulerContext = context.getScheduler().getContext();
} catch (SchedulerException ex) {
Logger.getLogger(MyTask.class.getName()).log(Level.SEVERE, null, ex);
}
MyObject externalInstance
= (MyObject) schedulerContext.get("externalInstance");
someDAO.doSomething(externalInstance.getSomething());
}
}
答案 0 :(得分:2)
由于我无法评论,请将其添加为答案
您没有使用JDBC-JobStoreTX
的原因JDBCJobStore用于在关系数据库中存储调度信息(作业,触发器和日历)。实际上有两个单独的JDBCJobStore类可供您选择,具体取决于您需要的事务行为。
JobStoreTX通过在每次操作(例如添加作业)后在数据库连接上调用commit()(或rollback())来管理所有事务本身。如果您在独立应用程序中使用Quartz,或者在应用程序未使用JTA事务时在servlet容器中使用,则JDBCJobStore是合适的。
这样您就可以将所需数据保存到JobDataMap
保存作业实例的状态信息。
将Job添加到调度程序时,JobDataMap实例将存储一次。在每次执行使用@PersistJobDataAfterExecution注释的作业后,它们也会被重新保留。
JobDataMap实例也可以与Trigger一起存储。如果您有一个存储在调度程序中的作业以供多个触发器定期/重复使用,但是每次独立触发,您希望为作业提供不同的数据输入。
在执行时传递给Job的JobExecutionContext还包含一个方便的JobDataMap,它是在Job的JobDataMap(如果有的话)上合并触发器的JobDataMap(如果有的话)内容的结果。