1. Quartz is introduced

Quartz is a richly featured, open source job scheduling library that can be integrated within virtually any Java application – from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components that may execute virtually anything you may program them to do. The Quartz Scheduler includes many enterprise-class features, such as support for JTA transactions and clustering.

2. The Quart instance

<dependency>
	<groupId>org.quartz-scheduler</groupId>
	<artifactId>quartz</artifactId>
	<version>2.3.0</version>
</dependency>
Copy the code
package cn.edu.neu.quartz;

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

import java.text.SimpleDateFormat;
import java.util.Date;

/ * * *@author32098 * /
public class QuartzJob implements Job {
    / * * * *@paramJobExecutionContext Job Executes the context object *@throws JobExecutionException ""
     */
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        // Write business logic
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(newDate())); }}Copy the code
package cn.edu.neu.quartz;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

/ * * *@author32098 * /
public class QuartzScheduler {
    public static void main(String[] args) throws SchedulerException, InterruptedException {
        // 1. Create Scheduler
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = schedulerFactory.getScheduler();
        // 2. Create JobDetail: Bind Job
        /* * Why? * JobDetail defines the task data (task name, etc.), while the real execution logic exists in the Job; * Since tasks can be executed concurrently, if Scheduler uses Job directly, there will be the problem of concurrent access to the same Job instance; * Using JobDetail & Job, each execution of Scheduler will create a new Job instance according to JobDetail to avoid concurrent access problems; * /
        JobDetail jobDetail = JobBuilder.newJob(QuartzJob.class)
                .withIdentity("time_print_job"."default_job_group")
                .build();
        // 3. Create Trigger
        /* * Trigger is a Quartz Trigger that informs the Scheduler when to execute the corresponding Job */
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("time_print_trigger"."default_trigger_group")
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever())
                .build();
        // 4. Start schedulerscheduler.scheduleJob(jobDetail, trigger); scheduler.start(); }}Copy the code

3. Quartz core

3.1 Job & JobDetail & JobDataMap(JobDetail)

  • The Job interface
package org.quartz;

public interface Job {
    void execute(JobExecutionContext var1) throws JobExecutionException;
}

Copy the code

The Job interface has only one execute method.

  • Job implementation class

We define a Job class that implements specific business logic by implementing the Job interface. Here is a Job that prints time:

package cn.edu.neu.quartz;

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

import java.text.SimpleDateFormat;
import java.util.Date;

/ * * *@author32098 * /
public class QuartzJob implements Job {
    / * * * *@paramJobExecutionContext Job Executes the context object *@throws JobExecutionException ""
     */
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        // Write business logic
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(newDate())); }}Copy the code

Stateful data attributes should not be defined in the Job implementation class, because the values of these attributes are not retained over multiple executions of the Job. You need to use JobDataMap to track the state of the Job

  • JobDetail (interface) and JobDetail JobDataMap
    • JobDetail is created by JobBuilder and contains many attributes of the Job instance
    • JobDataMap is part of JobDetail
    • JobDataMap can contain unlimited (serialized) data objects that can be used during Job instance execution
package cn.edu.neu.quartz;

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

import java.text.SimpleDateFormat;
import java.util.Date;

/ * * *@author32098 * /
public class QuartzJob implements Job {
    String timePrinterName;

    public void setTimePrinterName(String timePrinterName){
        this.timePrinterName = timePrinterName;
    }

    / * * * *@paramJobExecutionContext Job Executes the context object *@throws JobExecutionException ""
     */
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        // Write business logic
        System.out.println(timePrinterName+"\t"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                // if no timePrinterName and set method of timePrinterName, we need get printerName by
// String printerName = jobExecutionContext.getJobDetail().getJobDataMap().getString("timePrinterName");
// System.out.println(printerName+"\t"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));}}Copy the code
package cn.edu.neu.quartz;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

/ * * *@author32098 * /
public class QuartzScheduler {
    public static void main(String[] args) throws SchedulerException, InterruptedException {
        // 1. Create Scheduler
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = schedulerFactory.getScheduler();
        // 2. Create JobDetail: Bind Job
        JobDetail jobDetail1 = JobBuilder.newJob(QuartzJob.class)
                .withIdentity("time_print_job_1"."default_job_group")
                .usingJobData("timePrinterName"."time_printer_1")
                .build();
        JobDetail jobDetail2 = JobBuilder.newJob(QuartzJob.class)
                .withIdentity("time_print_job_2"."default_job_group")
                .usingJobData("timePrinterName"."time_printer_2")
                .build();
        // 3. Create Trigger
        Trigger trigger1 = TriggerBuilder.newTrigger()
                .withIdentity("time_print_trigger1"."default_trigger_group")
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever())
                .build();
        Trigger trigger2 = TriggerBuilder.newTrigger()
                .withIdentity("time_print_trigger2"."default_trigger_group")
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(10).repeatForever())
                .build();
        // 4. Start schedulerscheduler.scheduleJob(jobDetail1, trigger1); scheduler.scheduleJob(jobDetail2, trigger2); scheduler.start(); }}Copy the code

3.2 the Trigger

3.2.1 SimpleTrigger
  • SimpleTrigger meets the scheduling requirements:
    • Executes once at a specific point in time, or executes at a specific point in time and repeats several times at specified intervals
  • Important Settings for SimpleTrigger
    • The start time
    • The end of time
    • Repeat the number
    • Repetition interval
  • SimpleScheduleBuilder

See the above example for usage

3.2.2 CronTrigger
  • CronTrigger differs from SimpleTrigger in that it schedules jobs based on the calendar rather than at precisely specified intervals as per SimpleTrigger
  • However, CronTrigger and SimpleTrigger both have a startTime that specifies when to take effect, and an optional endTime that specifies when to stop the plan
  • Cron Expressions
    • Cron Expressions is a string of seven subexpression that describes the details of the calendar (subexpression separated by Spaces)
    • Cron Expressions
      1. Seconds: 0-59
      2. Minutes: 0-59
      3. Hours: 0-23
      4. Day-of-month: The value can be any value from 1 to 31. Note the number of days in a given Month
      5. Month: The Month can be specified as a value between 0 and 11, or use the strings JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, and DEC
      6. Day-of-week: The Day of the Week can be specified as a value between 1 and 7(1 = Sunday), or the strings SUN, MON, TUE, WED, THU, FRI, and SAT can be used
      7. Year: optional field
    • other
      • *: All possible values of the corresponding field, such as day-of-week
      • /: Specifies the increment of the value, 0/15 (minute) — every 15 minutes, starting from zero
      • L,W,#
  • When some scheduling requirements are too complex to be represented by a single trigger, two or more triggers can be created and registered to run the same job
  • CronScheduleBuilder

4. TriggerListeners & JobListeners & SchedulerListener

  • Listeners are objects we create to perform appropriate actions based on events that occur in the scheduler
  • TriggerListeners receive trigger events (trigger trigger, trigger failure, trigger completion) and JobListeners receive Job events (job impending execution, job completion notification). SchedulerListeners accept scheduler-related events (job/ trigger addition, job/ trigger deletion, critical errors in the scheduler, notification of scheduler closure, etc.)
  • Listeners are registered with the scheduler’s ListenerManager

5. Quartz configuration: Seewww.quartz-scheduler.org/documentati…