Location>code7788 >text

SpringBoot integration quartz timed tasks

Popularity:459 ℃/2024-10-30 17:10:59

Quartz Basic Concepts

Quartz is a task scheduling framework that is mainly used to trigger the execution of a task at a specific time. 

The core concepts of Quartz
Scheduler (Scheduler): responsible for task scheduling and management, including task start, pause, resume and other operations.
Task (Job): you need to implement the interface execute method, which defines the specific execution logic of the task.
Trigger (Trigger): defines the trigger conditions for task execution , including simple trigger (SimpleTrigger) and cron trigger (CronTrigger).
Task details (JobDetail): used to define the details of the task , such as task name , group name and so on.
JobBuilder and TriggerBuilder: used to define and build instances of tasks and triggers.
ThreadPool: used to schedule the execution of each job in parallel to improve efficiency.
Listeners (Listener): including task listeners, trigger listeners and scheduler listeners, used to listen to the task and trigger state changes.
The basic steps for using Quartz
Create a task class: implement the execute method of the Job interface to define the execution logic of the task.
Generate task details (JobDetail): through the JobBuilder to define the details of the task.
Generate triggers (Trigger): TriggerBuilder through the definition of the task trigger conditions , you can choose to use a simple trigger or cron trigger .
Get Scheduler (Scheduler): through the SchedulerFactory to create scheduler objects , and will be bound to the task and trigger to start the scheduler .
Pros and Cons of Quartz
Pros: support for complex scheduling needs , including timing , repeated execution , concurrent execution , etc.; provides a rich API and tool class , easy to use and maintain ; support for Spring integration , easy to apply in the Spring project .
Cons: complex configuration , requires some learning costs ; for simple timed tasks , the use of Quartz may be too complex .

Integration with SpringBoot

Step 1: Add a dependency

<dependency>
    <groupId></groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

Step 2: Create the scheduler

package ;

import ;
import ;
import ;
import ;
import ;
import ;

@Configuration
public class QuartzConfig {
    @Bean
    public Scheduler scheduler() throws SchedulerException {
        SchedulerFactory schedulerFactoryBean new StdSchedulerFactory();
        return ();
    }
}

Step 3: Create Job

import ;
import .slf4j.Slf4j;
import ;
import ;
import ;
import ;
import ;

import ;

@Slf4j
@Component
public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        JobDataMap jobDataMap = ().getJobDataMap();
        ("join:{}", ());
        ("Time to perform timed tasks:{}", (new Date()));
    }
}

 

Step 4: Create a task information class

import ;

@Data
public class JobInfo {
    private Long jobId;
    private String cronExpression;
    private String businessId;
}

Step 5: Create JobDetail and trigger creation wrapper classes

import ;
import ;
import .*;
import ;

public class QuartzBuilder {
    public static final String RUN_CRON ="Timed execution";
    public static final String RUN_ONE ="Execute once.";
    private static final String JOB_NAME_PREFIX ="flow";
    public static final String TRIGGER_NAME_PREFIX ="trigger.";

    public static JobDetail createJobDetail(JobInfo jobInfo, String type){
        String jobKey =JOB_NAME_PREFIX + ();
        if (RUN_ONE.equals(type)){
            jobKey = JOB_NAME_PREFIX + new Date().getTime();
        }

        return (MyJob.class)
                .withIdentity(jobKey,"my_group")
                .usingJobData("businessId",())
                .usingJobData("businessType","Other parameters")
                .storeDurably().build();
    }


    public static Trigger createTrigger(JobDetail jobDetail, JobInfo jobInfo){
        return ()
                .forJob(jobDetail)
                .withIdentity(TRIGGER_NAME_PREFIX + (),RUN_CRON)
                .withSchedule((()))
                .build();
        }
}

Step 6: The control layer interface implements the interfaces (execute once, start a timer, pause a task)

import ;
import ;
import .slf4j.Slf4j;
import .*;
import ;
import ;
import ;
import ;

@RestController
@Slf4j
public class QuartzController {

    @Autowired
    private Scheduler scheduler;

    /**
     * :: Timed task execution (one time only)
     *@return
     */
    @GetMapping("runOne")
    public  String runOne(){
        JobInfo jobInfo = new JobInfo();
        (1L);
        ("123");
        ("0/5 * * * * ?");
        JobDetail jobDetail = (jobInfo, QuartzBuilder.RUN_ONE);
        Trigger trigger = ()
                .forJob(jobDetail)
                .startNow()
                .withSchedule(().withRepeatCount(0))
                .build();

        try {
            (jobDetail, trigger);
            if (!()) {
                ();
            }
        } catch (SchedulerException e) {
            (());
            return "Execution failed.";
        }
        return "Implementation successful.";
    }

    /**
     * :: Commencement of timed execution
     *@return Implementation results
*/
    @GetMapping("start")
    public String start() {
        try {
            JobInfo jobInfo = new JobInfo();
            (1L);
            ("123");
            ("0/5 * * * * ?");
            TriggerKey triggerKey = new TriggerKey(QuartzBuilder.TRIGGER_NAME_PREFIX + (),QuartzBuilder.RUN_CRON);
            if ((triggerKey)) {
                (triggerKey);
            } else {
                JobDetail jobDetail = (jobInfo, QuartzBuilder.RUN_CRON);
                Trigger trigger = (jobDetail, jobInfo);
                (jobDetail, trigger);
                if (!()) {
                    ();
                }
            }
        } catch (SchedulerException e) {
            (());
            return "Execution failed.";

        }
        return "Implementation successful.";
    }

    /**
     * :: Discontinuation of mandate implementation
     *@return Implementation results
*/
    @GetMapping("pause")
    public String pause() {
        try {
            JobInfo jobInfo = new JobInfo();
            (1L);
            ("123");
            ("0/5 * * * * ?");
            TriggerKey triggerKey = new TriggerKey(QuartzBuilder.TRIGGER_NAME_PREFIX + (), QuartzBuilder.RUN_CRON);
            if ((triggerKey)) {
                (triggerKey);
            }
        } catch (SchedulerException e) {
            (());
            return "Execution failed.";
        }
        return "Implementation successful.";
    }

    /**
     * :: Querying tasks in their activated state and then re-executing them
*/
    @PostConstruct
    public void init(){
       ("Query tasks in the started state and re-execute them.");
        start();
    }

}

Finally access the interface:

http://localhost:8080/runOne

http://localhost:8080/start

http://localhost:8080/pause

The normal steps should look like this.

1, the creation of the task recorded in the task table job_info, at this time the initial state is 0

2. Update the status of the task table when starting a task to 1

3, if the application is closed, then the next time the application is started, you need to start the task with a status of 1 as well, so you don't need to think about tuning the interface to start again.