如何重新启动服务器关闭后动态创建的Quartz作业

时间:2016-12-09 20:26:05

标签: java spring spring-mvc cron quartz-scheduler

我正在使用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());
}

}

1 个答案:

答案 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(如果有的话)内容的结果。