Backend Development 21 min read

Integrating Quartz Scheduler with Spring Boot: Configuration, Job Definition, and Management

This article provides a comprehensive guide on using Quartz, a Java‑based job scheduling library, within a Spring Boot application, covering core concepts, Maven dependencies, scheduler configuration, job and trigger creation, concurrency handling, database integration, and practical code examples for managing scheduled tasks.

IT Architects Alliance
IT Architects Alliance
IT Architects Alliance
Integrating Quartz Scheduler with Spring Boot: Configuration, Job Definition, and Management

The article introduces Quartz, an open‑source Java job‑scheduling framework, and explains why modular integration is essential for customizable task start times in Spring Boot projects.

Core Quartz components are described: Job (the task class implementing execute() ), Trigger (e.g., SimpleTrigger and CronTrigger ), and Scheduler (which coordinates triggers and jobs). Official documentation links are provided.

Demo Maven dependencies for Quartz and Spring Boot starter are shown:

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.0</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

A simple MyJob class implementing org.quartz.Job is provided, followed by a main method that creates a SchedulerFactory , builds a JobDetail , configures a Trigger (executing every 30 seconds), schedules the job, and shuts down after one minute.

public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("任务被执行了。。。");
    }
}

public static void main(String[] args) throws Exception {
    SchedulerFactory factory = new StdSchedulerFactory();
    Scheduler scheduler = factory.getScheduler();
    JobDetail job = JobBuilder.newJob(MyJob.class)
        .withIdentity("job1", "group1")
        .build();
    Trigger trigger = TriggerBuilder.newTrigger()
        .withIdentity("trigger1", "group1")
        .startNow()
        .withSchedule(simpleSchedule()
            .withIntervalInSeconds(30)
            .repeatForever())
        .build();
    scheduler.scheduleJob(job, trigger);
    scheduler.start();
    TimeUnit.MINUTES.sleep(1);
    scheduler.shutdown();
}

The article explains JobDetail as the binding between a job and its data map, and why Quartz creates a new job instance for each execution to avoid concurrency issues.

JobExecutionContext provides access to the scheduler environment and job data during execution. The execute() method can retrieve parameters via context.getTrigger().getJobDataMap() or context.getJobDetail().getJobDataMap() .

For stateful jobs, the @PersistJobDataAfterExecution annotation is discussed, showing how to retain data across executions using JobDataMap . An example JobStatus class demonstrates incrementing a counter stored in the map.

@PersistJobDataAfterExecution
public class JobStatus implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        long count = (Long) context.getJobDetail().getJobDataMap().get("count");
        System.out.println("当前执行,第" + count + "次");
        context.getJobDetail().getJobDataMap().put("count", ++count);
    }
}

The article then covers Trigger configurations, including start/end times, SimpleTrigger for fixed‑interval execution, and CronTrigger for calendar‑based schedules, with a sample cron expression.

Integration with Spring Boot is detailed: adding spring-boot-starter-quartz dependency, configuring datasource and HikariCP properties, and creating a ScheduleConfig bean that sets Quartz properties (instance name, thread pool, JobStore, clustering, misfire policies, etc.).

@Configuration
public class ScheduleConfig {
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setDataSource(dataSource);
        Properties prop = new Properties();
        prop.put("org.quartz.scheduler.instanceName", "shivaScheduler");
        prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        prop.put("org.quartz.threadPool.threadCount", "20");
        prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
        prop.put("org.quartz.jobStore.isClustered", "true");
        // additional properties omitted for brevity
        factory.setQuartzProperties(prop);
        factory.setOverwriteExistingJobs(true);
        factory.setAutoStartup(true);
        return factory;
    }
}

Utility classes ScheduleUtils and ScheduleUtils methods ( createScheduleJob , handleCronScheduleMisfirePolicy , etc.) are presented to encapsulate job/trigger creation, misfire handling, and status management (pause, resume).

Concurrency control is explained: using @DisallowConcurrentExecution to prevent parallel execution of the same job definition, and combining it with @PersistJobDataAfterExecution for stateful jobs.

Finally, the article shows how to add, update, pause, and resume jobs via service methods that interact with the database and Quartz scheduler, and how to initialize all jobs at application startup by clearing the scheduler and re‑creating jobs from persisted records.

Additional notes cover excluding specific dates using calendars, and a disclaimer about promotional content unrelated to the technical guide.

backendJavaSpringBootCronQuartzJobScheduler
IT Architects Alliance
Written by

IT Architects Alliance

Discussion and exchange on system, internet, large‑scale distributed, high‑availability, and high‑performance architectures, as well as big data, machine learning, AI, and architecture adjustments with internet technologies. Includes real‑world large‑scale architecture case studies. Open to architects who have ideas and enjoy sharing.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.