springbooot integrates quartz and dynamically updates timed tasks

My last blog wrote about how to perform regular tasks according to a fixed cron, but now there is a demand: users add a memo (equivalent to an alarm clock), 30 minutes before the memo time, to actively push messages to users, then my last blog post is slightly inadequate, after a wave of Baidu, come up with the following methods

1. Create task classes

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

public class EventPushJob implements Job {
    private static int count = 0;
    @Override
    public void execute(JobExecutionContext jobExecutionContext){
        System.err.println("Dynamic determination is task push,The first"+ count++ +"second");
    }
}

2. Create a springboot startup task class.

Note: The CommandLineRunner class performs tasks at springboot startup

@Component
public class MyStartupRunner  implements CommandLineRunner {

    @Autowired
    private QuartzManager quartzManager;

    @Override
    public void run(String... args) throws Exception {
        System.out.println(">>>>>>>>>>>>>>>Timing Task Start Execution<<<<<<<<<<<<<");
        quartzManager.addJob("eventPushJob", "eventPushJobGroup", "eventPushTrigger", "eventPushTriggerGroup", EventPushJob.class, "0/1 * * * * ?");
    }
}

3. QuatzManager Tool Class

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class QuartzManager {

    @Autowired
    private final static SchedulerFactory schedulerFactory = new StdSchedulerFactory();

    /**
     * @Description: Add a timed task
     * @param jobName Task name
     * @param jobGroupName  Task group name
     * @param triggerName Trigger Name
     * @param triggerGroupName Trigger group name
     * @param jobClass  task
     * @param cron   Time settings, refer to quartz documentation
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void addJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName, Class jobClass, String cron) {
        try {
            Scheduler sched = schedulerFactory.getScheduler();
            // Task Name, Task Group, Task Execution Class
            JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
            // trigger
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
            // Trigger name, trigger group
            triggerBuilder.withIdentity(triggerName, triggerGroupName);
            triggerBuilder.startNow();
            // Flip-flop time setting
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
            // Creating Trigger Objects
            CronTrigger trigger = (CronTrigger) triggerBuilder.build();
            // Scheduling Container Settings JobDetail and Trigger
            sched.scheduleJob(jobDetail, trigger);
            // start-up
            if (!sched.isShutdown()) {
                sched.start();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: Modify the trigger time of a task
     * @param triggerName Trigger Name
     * @param triggerGroupName Trigger group name
     * @param cron   Time settings, refer to quartz documentation
     */
    public void modifyJobTime(String jobName,String jobGroupName, String triggerName, String triggerGroupName, String cron) {
        try {
            Scheduler sched = schedulerFactory.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
            if (trigger == null) {
                return;
            }
            String oldTime = trigger.getCronExpression();
            if (!oldTime.equalsIgnoreCase(cron)) {
                /** Way 1: Call rescheduleJob to start */
                // trigger
                TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
                // Trigger name, trigger group
                triggerBuilder.withIdentity(triggerName, triggerGroupName);
                triggerBuilder.startNow();
                // Flip-flop time setting
                triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
                // Creating Trigger Objects
                trigger = (CronTrigger) triggerBuilder.build();
                // Mode 1: modify the trigger time of a task
                sched.rescheduleJob(triggerKey, trigger);
                /** Mode 1: Call rescheduleJob to end */
                /** Mode 2: Delete first, and then create a new Job  */
                //JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));
                //Class<? extends Job> jobClass = jobDetail.getJobClass();
                //removeJob(jobName, jobGroupName, triggerName, triggerGroupName);
                //addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron);
                /** Mode 2: Delete first, and then create a new Job */
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: Remove a task
     */
    public void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) {
        try {
            Scheduler sched = schedulerFactory.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            sched.pauseTrigger(triggerKey);// Stop trigger
            sched.unscheduleJob(triggerKey);// Remove triggers
            sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));// Delete task
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * @Description:Start all timed tasks
     */
    public void startJobs() {
        try {
            Scheduler sched = schedulerFactory.getScheduler();
            sched.start();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description:Turn off all scheduled tasks
     */
    public void shutdownJobs() {
        try {
            Scheduler sched = schedulerFactory.getScheduler();
            if (!sched.isShutdown()) {
                sched.shutdown();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

The above three steps are configuring quartz's add, delete and change. Others update the timed tasks dynamically in the business code using the methods provided by quartz manager according to your needs.
Ideas: I control data in task code through redis

ps: Tool class (generating cron expressions based on specified time)

/**
 * Generate cron expression by entering a specified date and time
 * @return cron Expression
 */
public  String getCron(Date date){
    String dateFormat="ss mm HH dd MM ? yyyy";
    SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
    String formatTimeStr = null;
    if (date != null) {
        formatTimeStr = sdf.format(date);
    }
    return formatTimeStr;
}

Tags: SpringBoot Redis

Posted on Sat, 12 Oct 2019 11:12:38 -0700 by ProTec