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

标签 java spring spring-mvc cron quartz-scheduler

我正在使用 spring mvc 4.2.5.RELEASE 和quartz 2.2.1quartz-jobs 2.2.1

当用户输入quartz作业的名称和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);
        }
    }

这也很好用,我可以再次创建作业并且它们运行良好,

我的问题是我需要向任务类传递一个值,但我不知道如何传递它,当我第一次像这样创建作业时我知道如何传递它

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() 中为每个作业设置 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());
}

}

最佳答案

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

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

JDBCJobStore is used to store scheduling information (job, triggers and calendars) within a relational database. There are actually two seperate JDBCJobStore classes that you can select between, depending on the transactional behaviour you need.

JobStoreTX manages all transactions itself by calling commit() (or rollback()) on the database connection after every action (such as the addition of a job). JDBCJobStore is appropriate if you are using Quartz in a stand-alone application, or within a servlet container if the application is not using JTA transactions.

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

Holds state information for Job instances.

JobDataMap instances are stored once when the Job is added to a scheduler. They are also re-persisted after every execution of jobs annotated with @PersistJobDataAfterExecution.

JobDataMap instances can also be stored with a Trigger. This can be useful in the case where you have a Job that is stored in the scheduler for regular/repeated use by multiple Triggers, yet with each independent triggering, you want to supply the Job with different data inputs.

The JobExecutionContext passed to a Job at execution time also contains a convenience JobDataMap that is the result of merging the contents of the trigger's JobDataMap (if any) over the Job's JobDataMap (if any).

关于java - 如何重新启动服务器关闭后动态创建的 Quartz 作业,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41068337/

相关文章:

java - "Required MultipartFile parameter ' 使用 Angular 和 Spring 上传文件 ' is not present"

java - 如何在jdk11中实现java jdk14记录?

Java 反射框架和安全性

java - NoSuchMethodError : org. codehaus.jackson.type.JavaType

java - Keycloak - antMatcher 与请求的路径 Java 不匹配

java - Spring mvc 绑定(bind)错误国际化

java - 什么是 OutOfMemoryError 以及如何调试和修复它

java - 获取 ItemRequestForm.java 的修改版本以在 DSpace 版本 6x 中工作

java - Spring 批处理 : not able to access jobexecutionConext in flatfileitemwriter

java - 用于开发和生产的不同 URL。 (重新加载静态内容)