Dynamic Configuration of Quartz Scheduled Tasks in Spring Boot

This article demonstrates how to implement a dynamic, non‑blocking Quartz scheduler in a Spring Boot application, allowing tasks to be added, paused, resumed, deleted, or triggered instantly without restarting the service, and provides complete code examples and configuration steps.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Dynamic Configuration of Quartz Scheduled Tasks in Spring Boot

The article introduces the concept of dynamic configuration for scheduled tasks, pointing out the limitation of traditional XML‑based job definitions that require stopping the application and redeploying when a task’s schedule or status changes.

It reviews common Java scheduling options—JDK Timer, Quartz, and Spring Task—highlighting that Quartz, when configured via XML, is the simplest but still suffers from the same restart requirement.

To overcome this, the author presents a solution that leverages Quartz’s API to add, pause, resume, delete, and trigger jobs at runtime without downtime, using Spring Boot as the underlying framework.

<!-- quartz -->
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
</dependency>

The required database table sys_task stores job metadata such as name, description, cron expression, bean class, status, group, and audit fields.

CREATE TABLE `sys_task` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `job_name` varchar(255) DEFAULT NULL COMMENT '任务名',
  `description` varchar(255) DEFAULT NULL COMMENT '任务描述',
  `cron_expression` varchar(255) DEFAULT NULL COMMENT 'cron表达式',
  `bean_class` varchar(255) DEFAULT NULL COMMENT '任务执行时调用哪个类的方法 包名+类名',
  `job_status` varchar(255) DEFAULT NULL COMMENT '任务状态',
  `job_group` varchar(255) DEFAULT NULL COMMENT '任务分组',
  `create_user` varchar(64) DEFAULT NULL COMMENT '创建者',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_user` varchar(64) DEFAULT NULL COMMENT '更新者',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=32 DEFAULT CHARSET=utf8;

The implementation follows four steps:

Start the Spring Boot application and initialize a task‑listener component.

Read enabled tasks from the sys_task table and load each as a Quartz JobDetail and Trigger into the scheduler.

Let Quartz automatically execute the jobs according to their cron expressions.

Use a custom JobFactory (extending AdaptableJobFactory) to create job instances so that Spring can inject required services.

Quartz configuration class:

@Configuration
public class QuartzConfigration {
    @Autowired
    JobFactory jobFactory;

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        bean.setOverwriteExistingJobs(true);
        bean.setQuartzProperties(quartzProperties());
        bean.setJobFactory(jobFactory);
        return bean;
    }

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

    @Bean(name = "scheduler")
    public Scheduler scheduler() {
        return schedulerFactoryBean().getScheduler();
    }
}

Listener that runs on application start to load jobs:

@Component
@Order(1)
public class ScheduleJobInitListener implements CommandLineRunner {
    @Autowired
    TaskService scheduleJobService;

    @Override
    public void run(String... args) throws Exception {
        try {
            scheduleJobService.initSchedule();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Custom job factory to enable Spring bean injection into Quartz jobs:

@Component
public class JobFactory extends AdaptableJobFactory {
    @Autowired
    AutowireCapableBeanFactory capableBeanFactory;

    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        Object jobInstance = super.createJobInstance(bundle);
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}

Sample job implementation that prints a message with the current time:

@DisallowConcurrentExecution
@Component
public class HelloWorldJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("欢迎使用yyblog,这是一个定时任务  --小卖铺的老爷爷!" + DateUtils.fullTime(new Date()));
    }
}

Utility methods for common job operations (pause, resume, delete, trigger now, update cron) are provided, each using the Quartz Scheduler API:

public void pauseJob(TaskDO task) throws SchedulerException {
    JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());
    scheduler.pauseJob(jobKey);
}

public void resumeJob(TaskDO task) throws SchedulerException {
    JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());
    scheduler.resumeJob(jobKey);
}

public void deleteJob(TaskDO task) throws SchedulerException {
    JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());
    scheduler.deleteJob(jobKey);
}

public void runJobNow(TaskDO task) throws SchedulerException {
    JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());
    scheduler.triggerJob(jobKey);
}

public void updateJobCron(TaskDO task) throws SchedulerException {
    TriggerKey triggerKey = TriggerKey.triggerKey(task.getJobName(), task.getJobGroup());
    CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
    CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.getCronExpression());
    trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
    scheduler.rescheduleJob(triggerKey, trigger);
}

Finally, the article concludes that the presented code provides a lightweight, dynamic scheduling solution for Spring Boot applications, enabling administrators to manage Quartz jobs at runtime without restarting the service.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Dynamic ConfigurationSpring BootQuartzScheduled Tasks
Java Architect Essentials
Written by

Java Architect Essentials

Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.

0 followers
Reader feedback

How this landed with the community

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.