springboot integrates quartz to implement a timed task example

  • 2020-06-23 00:31:05
  • OfStack

There are timer tasks when you are working on a project, such as what should be done at such and such a time, how many seconds should be spent, and so on.

spring supports the implementation of multiple timed tasks. Let's talk about using the spring timer and using the quartz timer

1. We use ES8en-ES9en as the basic framework. The concept is zero configuration file, all configuration is based on annotation and exposure of bean.

2. Use the spring timer:

spring comes with a timer - enabled task implementation. It can be configured to use simple timing tasks.


@Component
@Configurable
@EnableScheduling
public class ScheduledTasks{

  @Scheduled(fixedRate = 1000 * 30)
  public void reportCurrentTime(){
    System.out.println ("Scheduling Tasks Examples: The time is now " + dateFormat ().format (new Date ()));
  }

  // every 1 Minutes to perform 1 time 
  @Scheduled(cron = "0 */1 * * * * ")
  public void reportCurrentByCron(){
    System.out.println ("Scheduling Tasks Examples By Cron: The time is now " + dateFormat ().format (new Date ()));
  }

  private SimpleDateFormat dateFormat(){
    return new SimpleDateFormat ("HH:mm:ss");
  }
  
}

No, that's right, the timing task with spring is that simple, and there are a few important notes:

EnableScheduling: Note the start timer task.

@Scheduled (fixedRate = 1000 * 30) defines a timed task.

3. Use quartz to achieve timed tasks.

Quartz designers made a design choice to separate jobs from scheduling. Triggers in Quartz are used to tell the scheduler when a job will fire. The framework provides 1 trigger type, but the two most commonly used are SimpleTrigger and CronTrigger. The SimpleTrigger is designed for simple fire dispatching. Typically, if you need the number of seconds to wait between a given time and the number of repetitions or two fires to fire 1 job, SimpleTrigger is for you. On the other hand, if you have a lot of complex job scheduling, you may need CronTrigger.

CronTrigger is scheduled based on ES45en-ES46en. Use CronTrigger when you need to perform assignments at 10:30 a.m. every day except Saturday and Sunday. As its name implies, CronTrigger is based on Unix clone expressions.

Using quartz says using maven dependencies.


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

Since we are using the ES57en-ES58en framework, which is designed to have zero profiles, we do not use the PROFILE of the xml file to define a timer, but instead expose bean to the spring container.

Expose the bean required to the spring container


@Configuration
public class SchedledConfiguration {

  //  It's set in configuration 
  //  1.  targetMethod:  Specifies that scheduled execution is required scheduleInfoAction In the simpleJobTest() methods 
  //  2.  concurrent : For the same JobDetail , when specifying multiple Trigger when ,  Probably the first 1 a job And before I do that, 
  //  The first 2 a job Here we go. The specified concurrent Set to false More than, job Will not run concurrently, no 2 a job Will not be in the first 1 a job Start before you finish. 
  //  3.  cronExpression : 0/10 * * * * ? each 10 Seconds to perform 1 For details, please refer to the attached table. 
  //  (4)  triggers : By adding others ref Elements can be list Multiple triggers are placed in.  scheduleInfoAction In the simpleJobTest() methods 
  @Bean(name = "detailFactoryBean")
  public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduledTasks scheduledTasks){
    MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean ();
    bean.setTargetObject (scheduledTasks);
    bean.setTargetMethod ("reportCurrentByCron");
    bean.setConcurrent (false);
    return bean;
  }

  @Bean(name = "cronTriggerBean")
  public CronTriggerBean cronTriggerBean(MethodInvokingJobDetailFactoryBean detailFactoryBean){
    CronTriggerBean tigger = new CronTriggerBean ();
    tigger.setJobDetail (detailFactoryBean.getObject ());
    try {
      tigger.setCronExpression ("0/5 * * * * ? ");// every 5 Seconds to perform 1 time 
    } catch (ParseException e) {
      e.printStackTrace ();
    }
    return tigger;

  }

  @Bean
  public SchedulerFactoryBean schedulerFactory(CronTriggerBean[] cronTriggerBean){
    SchedulerFactoryBean bean = new SchedulerFactoryBean ();
    System.err.println (cronTriggerBean[0]);
    bean.setTriggers (cronTriggerBean);
    return bean;
  }
}

MethodInvokingJobDetailFactoryBean: This factory is mainly used to produce 1 jobDetail, that is, 1 task. Because the timing task that we're doing is essentially performing one method. So it's convenient to use this factory.

Note: setTargetObject is set to 1 object instead of 1 class.

CronTriggerBean: Define 1 trigger.

Note: setCronExpression: is an expression that throws an exception if it is out of specification.

SchedulerFactoryBean: Main managed plant, this is the main 1 bean. quartz manages the triggers in this factory.

4. Encapsulation of quartz

As you can see from the above code, we are setting a fixed cronExpression here, so for project use, we usually need to set it dynamically such as pulling it out of the database.

It is also quite simple to do this. We only need to define 1 Trigger to inherit from CronTriggerBean. The setCronExpression method is enough.

So another problem, if we want to define two timed tasks, it will be troublesome, we need to inject 1 task factory first, and then inject 1 trigger.

To reduce this configuration, we define an abstract superclass to inherit from CronTriggerBean.

The specific code is as follows:


public abstract class BaseCronTrigger extends CronTriggerBean implements Serializable {

  private static final long serialVersionUID = 1L;

  public void init(){
    //  To get the task 
    JobDetail jobdetail = new JobDetail (this.getClass ().getSimpleName (),this.getMyTargetObject ().getClass ());
    this.setJobDetail (jobdetail);
    this.setJobName (jobdetail.getName ());
    this.setName (this.getClass ().getSimpleName ());
    try {
      this.setCronExpression (this.getMyCronExpression ());
    } catch (java.text.ParseException e) {
      e.printStackTrace ();
    }

  }

  public abstract String getMyCronExpression();

  public abstract Job getMyTargetObject();

}

Its init() method to bind the task for this trigger. Its task is of type Job, that is, the task it executes is a class that implements the Job interface, and the task will have an execute() method to execute the task question.


public class ScheduledTasks implements Job {
  
  @Override
  public void execute(JobExecutionContext context) throws JobExecutionException{
    System.out.println ("Scheduling Tasks Examples By Cron: The time is now " + dateFormat ().format (new Date ()));
  }

  private SimpleDateFormat dateFormat(){
    return new SimpleDateFormat ("HH:mm:ss");
  }
}

To add a task to the trigger, we need to call the init() method in the subclass, where we call the init () method because the spring container is injected with a null parameter.


@Component
public class InitializingCronTrigger extends BaseCronTrigger implements Serializable {

  private static final long  serialVersionUID = 1L;

  @Autowired
  private SchedulerFactoryBean schedulerFactoryBean;

  public InitializingCronTrigger() {
    init ();
  }

  @Override
  public String getMyCronExpression(){
    return "0/5 * * * * ?";
  }

  @Override
  public Job getMyTargetObject(){
    return new ScheduledTasks ();
  }

  public void parse(){
    try {
      schedulerFactoryBean.getObject ().pauseAll ();
    } catch (SchedulerException e) {
      e.printStackTrace ();
    }
  }

}

At this point, we only need to add 1 configuration to the configuration class.


 @Bean
  public SchedulerFactoryBean schedulerFactory(CronTriggerBean[] cronTriggerBean){
    SchedulerFactoryBean bean = new SchedulerFactoryBean ();
    System.err.println (cronTriggerBean[0]);
    bean.setTriggers (cronTriggerBean);

    return bean;
  }

4. Introduce an cronExpression expression

字段 允许值 允许的特殊字符
0-59 , - * /
0-59 , - * /
小时 0-23 , - * /
日期 1-31 , - * / L W C
月份 1-12 或者 JAN-DEC , - * /
星期 1-7 或者 SUN-SAT , - * / L C #
年(可选) 留空, 1970-2099 , - * /

As shown in the above expression:

The "*" character is used to specify all values. For example, "*" indicates "per minute" in the minute field.

The "-" character is used to specify a range. For example, "10-12" in the small time domain means "10, 11, 12".

The ", "character is used to specify additional values. For example, "MON,WED,FRI" in the week domain means "Monday.

"The & # 63;" Characters are used only in the date and week fields. It is used to specify "non-explicit values". It is useful when you need to specify something by one of these two fields. Take a look at the following example to see why.

The "L" character specifies a day of the month or week (the last day). Short for "Last". However, "L" means different meanings in week and month. For example, "L" refers to the last day of the month -- January 31 and February 28 in the month segment. If it is in the week field, it simply means "7" or "SAT". If value is worth in the week field, it means "the last week of the month". For example, "6L" means the last week 5 of the month.

The "W" character can only be used in the month field, which specifies the Sunday closest to the specified date.

The "#" character can only be used in the week field, which specifies the day of the week value is in the month

Each element can explicitly specify a value (such as 6), an interval (such as 9-12), a list (such as 9, 11, 13), or a wildcard (such as *). The "date in month" and "date in week" elements are mutually exclusive, so you should set a question mark (?). To indicate which field you don't want to set. Table 7.1 shows 1 examples of cron expressions and what they mean:

表达式

意义
"0 0 12 * * ?" 每天中午12点触发
"0 15 10 ? * *" 每天上午10:15触发
"0 15 10 * * ?" 每天上午10:15触发
"0 15 10 * * ? *" 每天上午10:15触发
"0 15 10 * * ? 2005" 2005年的每天上午10:15触发
"0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发
"0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发
"0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
"0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发
"0 10,44 14 ? 3 WED" 每年3月的星期3的下午2:10和2:44触发
"0 15 10 ? * MON-FRI" 周1至周5的上午10:15触发
"0 15 10 15 * ?" 每月15日上午10:15触发
"0 15 10 L * ?" 每月最后1日的上午10:15触发
"0 15 10 ? * 6L" 每月的最后1个星期5上午10:15触发
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后1个星期5上午10:15触发
"0 15 10 ? * 6#3" 每月的第3个星期5上午10:15触发

Every morning at 6:06 * * *

Every two hours 0 */2 * * *

Every two hours between 11:00 p.m. and 8:00a.m., 023-7/2, 8 * * *

On the 4th of every month and from The 1st to the 3rd of every week, 11:00 am, 11:00 am, 4 * 1-3

January 1 at 4:04 a.m


Related articles: