【问题标题】:How to start again Quartz jobs that are created dynamically after a server shutdown如何重新启动服务器关闭后动态创建的 Quartz 作业
【发布时间】:2017-04-25 09:35:27
【问题描述】:

我正在使用 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() 中从数据库中获取它们时,我不知道如何执行此操作

如何在我的方法 reCreateJobs() 中为每个 Job 设置该 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());
}

}

【问题讨论】:

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


    【解决方案1】:

    由于我无法发表评论,因此将其添加为答案

    您不使用JDBC-JobStoreTX的任何原因

    JDBCJobStore 用于在关系数据库中存储调度信息(作业、触发器和日历)。实际上有两个单独的 JDBCJobStore 类可供您选择,具体取决于您需要的事务行为。

    JobStoreTX 通过在每次操作(例如添加作业)后在数据库连接上调用 commit()(或 rollback())来管理所有事务本身。如果您在独立应用程序中使用 Quartz,或者如果应用程序不使用 JTA 事务,则在 servlet 容器中使用 JDBCJobStore 是合适的。

    这样你就可以把你想要的数据持久化到JobDataMap

    保存 Job 实例的状态信息。

    JobDataMap 实例在将 Job 添加到调度程序时存储一次。每次执行带有 @PersistJobDataAfterExecution 注释的作业后,它们也会重新持久化。

    JobDataMap 实例也可以与触发器一起存储。如果您有一个作业存储在调度程序中以供多个触发器定期/重复使用,但对于每个独立的触发,您希望为作业提供不同的数据输入,这可能会很有用。

    在执行时传递给 Job 的 JobExecutionContext 还包含一个便利的 JobDataMap,它是将触发器的 JobDataMap(如果有)的内容与 Job 的 JobDataMap(如果有)合并的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-21
      • 2019-02-21
      • 2017-07-29
      • 2018-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多