避免 Quartz 每次都创建新实例

Avoid Quartz creating new instance every time

Quartz 每次都通过 JobBuilder 创建 class 的新实例

JobBuilder.newJob(MyJob.class)

但是,我只想要一个 MyJob 实例,并且只从 execute 函数中触发 testFunction,我该如何让它工作?

我发现通过 QuartzGuiceLib 我可以使用一些注释来实现它,通过 Spring 我可以在配置文件中更改一些东西。但是如何在没有任何框架的情况下通过纯 Java 实现它呢?

下面是代码截图:

public class MyJob implements Job {
    public MyJob() {
        testFunction();

        try {
            final Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
            if (!scheduler.checkExists(JOB_KEY)) {
                triggerScheduler(scheduler);
            } else {
                log.info("Job with key {{}} already exist", JOB_KEY);
            }
        } catch (SchedulerException e) {
            log.error("Fail to start scheduler", e);
        }
    }

    public void testFunction() {
    }

    private void triggerScheduler(final Scheduler scheduler) throws SchedulerException {
        final JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                .withIdentity(JOB_KEY)
                .build();

        final Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("myjob")
                .withSchedule(
                        simpleSchedule()
                                .withIntervalInSeconds(60)
                                .repeatForever())
                .build();

        scheduler.start();

        log.info("Scheduling job with key {{}}", jobDetail.getKey());

        scheduler.scheduleJob(jobDetail, trigger);
    }

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        testFunction();
    }
}

将作业和调度程序保持在两个单独的 class 中可能更容易,如下所示:

public class MyQuartzScheduler {
    public static void main( String[] args ) throws Exception {
        JobDetail job = JobBuilder.newJob(MyJob.class)
        .withIdentity("dummyJobName", "group1").build();

        Trigger trigger = TriggerBuilder
        .newTrigger()
        .withIdentity("MyJobTrigger", "group1")
        .withSchedule(
            CronScheduleBuilder.cronSchedule("0 * * * * ?"))
        .build();

        Scheduler scheduler = new StdSchedulerFactory().getScheduler();
        scheduler.start();
        scheduler.scheduleJob(job, trigger);
    }
}

然后是你的工作Class:

public class MyJob implements Job {    
    public void testFunction() {
        System.out.println("Running Test!");
    }

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        testFunction();
    }
}

这是从以下位置找到的 mkyong 教程文章改编而来:

https://www.mkyong.com/java/quartz-2-scheduler-tutorial/

不过,为了回答您的问题,Quartz 会根据 运行 创建一个新实例:

您可以制作另一个静态 class 或您的作业 class 将调用的工厂,它会在每次调用时使用相同的实例。

public class MyJob implements Job {

    public void testFunction() {
        MyClassWithStaticCounter.increaseCounter(1);
        System.out.println(MyClassWithStaticCounter.getCounter());
    }

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        testFunction();
    }
}

你的 class 有静态内容:

public class MyClassWithStaticCounter {
    private static int counter = 0;

    public static void increaseCounter(int i){
        counter += i;
    }

    public static int getCounter(){
        return counter;
    }
}