How to Inject Spring Beans into Quartz Jobs

Lokesh Gupta

By default, Quartz does not recognize Spring beans configured in applicationContext.xml or with @Bean annotation. If we try to @Autowired these beans in Quartz Job or QuartzJobBean, we will get NullPointerException.

1. Injecting Spring ApplicationContext to QuartzJobBean

The solution is to inject Spring’s ApplicationContext instance to org.quartz.SchedulerContext which is available using org.quartz.JobExecutionContext parameter to executeInternal() method.

1.1. Inject ApplicationContext to SchedulerContext

This is typical SchedulerFactoryBean bean entry. Use setApplicationContextSchedulerContextKey() method. This method set the key of an ApplicationContext reference to expose in the SchedulerContext.

@Bean
public SchedulerFactoryBean schedulerFactoryBean() throws IOException, SchedulerException 
{
  SchedulerFactoryBean scheduler = new SchedulerFactoryBean();
  scheduler.setTriggers(jobOneTrigger(), jobTwoTrigger());
  scheduler.setQuartzProperties(quartzProperties());
  scheduler.setJobDetails(jobOneDetail(), jobTwoDetail());
  scheduler.setApplicationContextSchedulerContextKey("applicationContext");
  return scheduler;
}

1.2. Access Injected Beans in QuartzJobBean

Now, all you need to do is – get applicationContext reference and start fetching beans as per your need.

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.configuration.JobLocator;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;
 
public class CustomQuartzJob extends QuartzJobBean {
 
  private String jobName;
  private JobLauncher jobLauncher;
  private JobLocator jobLocator;
 
  public String getJobName() {
    return jobName;
  }
 
  public void setJobName(String jobName) {
    this.jobName = jobName;
  }
 
  @Override
  protected void executeInternal(JobExecutionContext context) throws JobExecutionException 
  {
    try
    {
      ApplicationContext applicationContext = (ApplicationContext) 
              context.getScheduler().getContext().get("applicationContext");
 
      jobLocator = (JobLocator) applicationContext.getBean(JobLocator.class);
      jobLauncher = (JobLauncher) applicationContext.getBean(JobLauncher.class);
 
      Job job = jobLocator.getJob(jobName);
      JobParameters params = new JobParametersBuilder()
          .addString("JobID", String.valueOf(System.currentTimeMillis()))
          .toJobParameters();
 
      jobLauncher.run(job, params);
    } 
    catch (Exception e) 
    {
      e.printStackTrace();
    }
  }
}

Now when you run quartz job, you will get the jobLocator and jobLauncher instances in executeInternal() method.

2. Conclusion

In this tutorial, we learned to inject the Spring context beans into QuartzJobBean instance so we can get or set the quartz properties in the runtime.

Drop me your questions in the comments section.

Happy Learning !!

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode