spring-boot-starter-quartz 实现作业与扩展 QuartzJobBean

spring-boot-starter-quartz implements job vs extends QuartzJobBean

我在我的一个项目中使用 Quartz Scheduler。创建 Quartz 作业主要有两种方式:

  1. 实施org.quartz.Jobclass
  2. 扩展 org.springframework.scheduling.quartz.QuartzJobBean(实现 org.quartz.Job class)

QuartzJobBean javadoc 的最后一部分令人困惑:

* Note that the preferred way to apply dependency injection to Job instances is via a JobFactory: 
that is, to specify SpringBeanJobFactory as Quartz JobFactory (typically via
SchedulerFactoryBean.setJobFactory SchedulerFactoryBean's "jobFactory" property}). 
This allows to implement dependency-injected Quartz Jobs without a dependency on Spring base classes.*

对于纯粹的 Spring(或 SpringBoot)使用,我想最好扩展 QuartzJobBean。我说的对吗?

首先,由于 QuartzJobBeanJob,任何接受 Job 的 API 调用都会接受 QuartzJobBean,但是反之亦然。因此,如果您需要一个 QuartzJobBean,因为某些 API 调用希望您传递一个,那么这就是您的答案。

否则,答案取决于您是否想使用(并绑定)QuartzJobBean 提供的功能。如果您查看 class 的源代码,您会发现 subclassing QuartzJobBean 相对于实现 Job 的唯一好处是 QuartzJobBean 在将控制权传递给您的代码之前执行此逻辑:

    try {
        BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
        MutablePropertyValues pvs = new MutablePropertyValues();
        pvs.addPropertyValues(context.getScheduler().getContext());
        pvs.addPropertyValues(context.getMergedJobDataMap());
        bw.setPropertyValues(pvs, true);
    }
    catch (SchedulerException ex) {
        throw new JobExecutionException(ex);
    }

因此,如果您扩展 QuartzJobBean class 并实现 executeInternal 方法,此代码将在您的代码之前运行。如果您实现 Job class 和 execute 方法,则不会。就作业运行时实际发生的情况而言,这是这两种方法之间的唯一区别。

所以要回答你的问题,问问自己“我想利用上面的代码吗?”。如果答案是肯定的,那么扩展 QuartzJobBean 以利用该功能。如果你不需要这个添加的功能,不想要它,and/or 不想被锁定在上面代码隐含的依赖关系中,那么你应该实现 Job 来避免这个代码及其依赖项。我个人的方法是实施 Job 除非我有某种理由改为扩展 QuartzJobBean