Spring boot

Spring boot quartz scheduler example

Spring boot with Quartz integration

Spring Boot offers several conveniences for working with the Quartz scheduler, including the spring-boot-starter-quartz “Starter”. If Quartz is available, a Scheduler is auto-configured (through the SchedulerFactoryBean abstraction).

Beans of the following types are automatically picked up and associated with the Scheduler:

JobDetail: Defines a particular Job. JobDetail instances can be built with the JobBuilder API.

Calendar: Defines when a particular job is triggered based on calendar days

Trigger: Defines when a particular job is triggered.

Configure quartz starter (pom.xml)

	<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.spring-boot-quartz</groupId>
	<artifactId>Spring-Boot-Quartz</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>Spring-Boot-Quartz Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.4.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
		</dependency>
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz</artifactId>
		</dependency>
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz-jobs</artifactId>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
		<finalName>Spring-Boot-Quartz</finalName>
	</build>
</project>

Create a simple quartz job (SimpleJob.java)

package com.candidjava.springboot;

import org.quartz.Job;
import org.quartz.JobExecutionContext;

public class SimpleJob implements Job {

 @Override
 public void execute(JobExecutionContext jobExecutionContext) {

  System.out.println("Candidjava welcomes simple job");

 }
}

Configure Quartz properties

You can refer default configuration from Spring boot website

application.yml

simplejob:
   frequency: 1000

quartz.yml

org:
   quartz:
      scheduler:
         instanceName: springBootQuartzApp
         instanceId: AUTO
         threadCount: 1

Configure quartz job (SchedulerConfig.java)

JobFactory

A JobFactory is responsible for producing instances of Job classes. This interface helps spring boot application to create dependency injection and autowire them when required.

SchedulerFactoryBean

FactoryBean that creates and configures a Quartz Scheduler, manages its lifecycle as part of the Spring application context and exposes the Scheduler as bean reference for dependency injection.

Allows registration of JobDetails, Calendars, and Triggers, automatically starting the scheduler on initialization and shutting it down on destruction. In scenarios that just require static registration of jobs at startup, there is no need to access the Scheduler instance itself in application code.

SimpleTriggerFactoryBean

A Spring FactoryBean for creating a Quartz SimpleTrigger instance, supporting bean-style usage for trigger configuration.

SimpleTrigger(Impl) itself is already a JavaBean but lacks sensible defaults. This class uses the Spring bean name as job name, the Quartz default group (“DEFAULT”) as job group, the current time as start time, and indefinite repetition, if not specified.

JobDetailFactoryBean

JobDetail(Impl) itself is already a JavaBean but lacks sensible defaults. This class uses the Spring bean name as job name, and the Quartz default group (“DEFAULT”) as job group if not specified.

 

package com.candidjava.springboot;

import java.io.IOException;
import java.util.Properties;

import org.quartz.JobDetail;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.spi.JobFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;

@Configuration
public class SchedulerConfig {

 @Bean
 public JobFactory jobFactory(ApplicationContext applicationContext) {
  SpringJobFactory jobFactory = new SpringJobFactory();
  jobFactory.setApplicationContext(applicationContext);
  return jobFactory;
 }

 @Bean
 public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory,
  Trigger simpleJobTrigger) throws IOException {
  SchedulerFactoryBean factory = new SchedulerFactoryBean();
  factory.setJobFactory(jobFactory);
  factory.setQuartzProperties(quartzProperties());
  factory.setTriggers(simpleJobTrigger);
  System.out.println("starting jobs....");
  return factory;
 }

 @Bean
 public SimpleTriggerFactoryBean simpleJobTrigger(
  @Qualifier("simpleJobDetail") JobDetail jobDetail,
  @Value("${simplejob.frequency}") long frequency) {
  System.out.println("simpleJobTrigger");

  SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
  factoryBean.setJobDetail(jobDetail);
  factoryBean.setStartDelay(0 L);
  factoryBean.setRepeatInterval(frequency);
  factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
  return factoryBean;
 }

 @Bean
 public Properties quartzProperties() throws IOException {
  PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
  propertiesFactoryBean.setLocation(new ClassPathResource(
   "/quartz.yml"));
  propertiesFactoryBean.afterPropertiesSet();
  return propertiesFactoryBean.getObject();
 }

 @Bean
 public JobDetailFactoryBean simpleJobDetail() {
  JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
  factoryBean.setJobClass(SimpleJob.class);
  factoryBean.setDurability(true);
  return factoryBean;
 }
}

Inject quartz job (SpringJobFactory.java)

Supports Spring-style dependency injection on bean properties. This is essentially the direct equivalent of Spring’s QuartzJobBean in the shape of a Quartz JobFactory.

package com.candidjava.springboot;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;

public final class SpringJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {


 private transient AutowireCapableBeanFactory beanFactory;
 @Override
 public void setApplicationContext(final ApplicationContext context) {
  beanFactory = context.getAutowireCapableBeanFactory();
 }

 @Override
 protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
  final Object job = super.createJobInstance(bundle);
  System.out.println("create job instance");
  beanFactory.autowireBean(job);
  return job;
 }
}
 

Launch spring boot application (Application.java)

package com.candidjava.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

 public static void main(String[] args) {
  SpringApplication.run(Application.class, args);
 }
}

Download

Download source code from my github account Click here

About the author

Mathan Lal

2 Comments

Click here to post a comment