Search code examples
spring-bootjobsquartz

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


I'm using Quartz Scheduler in one of my projects. There are two main ways to create a Quartz job:

  1. implement org.quartz.Job class
  2. extend org.springframework.scheduling.quartz.QuartzJobBean (which implements org.quartz.Job class)

The last part of the QuartzJobBean javadoc is confusing :

* 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.*

For a pure Spring (or SpringBoot) use, I suppose that it is better to extend QuartzJobBean. I'm right?


Solution

  • First of all, since a QuartzJobBean is a Job, any API call that will accept a Job will accept a QuartzJobBean, but not visa versa. So if you need a QuartzJobBean because some API call expects you to pass it one, then there's your answer.

    Otherwise, the answer depends on if you want to make use of (and be tied to) the functionality provided by QuartzJobBean. If you look at the source code for that class, you'll see that the sole gain in subclassing QuartzJobBean over implementing Job, is that QuartzJobBean performs this logic before passing control to your code:

        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);
        }
    

    So if you extend the QuartzJobBean class and implement the executeInternal method, this code runs before your code. If you implement the Job class and the execute method, it does not. That's the only difference between the two approaches in terms of what actually happens when your job runs.

    So to answer your question, ask yourself "do I want to take advantage of the above code?". If the answer is Yes, then extend QuartzJobBean to take advantage of that functionality. If you don't need this added functionality, don't want it, and/or don't want to be locked into the dependencies implied by the above code, then you should implement Job to avoid this code and its dependencies. My personal approach would be to implement Job unless I had some reason to extend QuartzJobBean instead.