Detailed explanation of springboot timing tasks


In the process of our project development, we often need timed tasks to help us do some content. Spring Boot has already implemented it for us by default, and we only need to add corresponding annotations to achieve it.

1. Annotation-based (static)

1. Add dependencies

  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
  </dependency>
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
  </dependency>

2. Create a scheduled task

Timing task 1:

@Configuration
@EnableScheduling
public class SchedulerTask1 {
    
    

    private int count=0;

    @Scheduled(cron="*/6 * * * * ?")
    private void process(){
    
    
        System.out.println("this is scheduler task runing  "+(count++));
    }

}

Timed task 2:

@Configuration
@EnableScheduling
public class SchedulerTask2 {
    
    

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    @Scheduled(fixedRate = 6000)
    public void reportCurrentTime() {
    
    
        System.out.println("现在时间:" + dateFormat.format(new Date()));
    }

}

The result is as follows:

this is scheduler task runing  0
现在时间:09:44:17
this is scheduler task runing  1
现在时间:09:44:23
this is scheduler task runing  2
现在时间:09:44:29
this is scheduler task runing  3
现在时间:09:44:35

3. Parameter description

@ConfigurationIt is used to mark the configuration class and has the effect of Component.

@EnableSchedulingIndicates that the scheduled task is enabled

@ScheduledThe parameter can accept two timing settings, one is our common one cron="*/6 * * * * ?", and the other is fixedRate = 6000that both of them mean to print the content every six seconds.

fixedRate Description

  • @Scheduled(fixedRate = 6000): Execute again 6 seconds after the last execution time point

  • @Scheduled(fixedDelay = 6000): Execute again 6 seconds after the last execution time point

  • @Scheduled(initialDelay=1000, fixedRate=6000): Execute after the first delay of 1 second, then execute every 6 seconds according to the fixedRate rule

The cron attribute specifies the task execution rules in the form of expressions, and also starts timing from the completion of the last task execution. The expression rules are as follows:

The rules for each location are as follows:

insert image description here

Remark:

  • Asterisk (*): It can be used in all fields to indicate every moment in the corresponding time field, for example, * in the minute field means "every minute".
  • Question mark (?): This character is only used in date and week fields, and it is usually designated as a "meaningless value", which is equivalent to a placeholder.
  • Minus sign (-): Express a range, such as using "10-12" in the hour field, it means from 10 to 12 o'clock, that is, 10,11,12.
  • Comma (,): Express a list value, such as using "MON, WED, FRI" in the week field, it means Monday, Wednesday and Friday.
  • Slash (/): x/y expresses a sequence of equal steps, x is the starting value, and y is the incremental step value. If you use 0/15 in the seconds field, it means 0, 15, 30 and 45 seconds, and 5/15 means 5, 20, 35, 50 in the minutes field, you can also use */y, which is equivalent to at 0/y.
  • L: This character is only used in the date and week fields, representing the meaning of "Last", but it has different meanings in the two fields. L in the date field means the last day of the month, such as the 31st of January and the 28th of February in a non-leap year; if L is used in the middle of the week, it means Saturday, which is equivalent to 7. However, if L appears in the day of the week field and is preceded by a numeric X, it means "the last X days of the month", for example, 6L means the last Friday of the month.
  • W: This character can only appear in the date field, and it is a modification of the leading date, indicating the nearest working day to the date. For example, 15W means the closest working day to the 15th of the month. If the 15th of the month is a Saturday, match Friday the 14th; if the 15th is a Sunday, match Monday the 16th; if the 15th is a Tuesday, the result is 15 No. Tuesday. But it must be noted that the associated matching date cannot span months. For example, if you specify 1W, if the 1st is a Saturday, the result will match Monday the 3rd, not the last day of the previous month. A W string can only specify a single date, not a range of dates.
  • LW combination: LW can be combined in the date field, which means the last working day of the current month.
  • Pound sign (#): This character can only be used in the week field, indicating a certain working day of the month. For example, 6#3 means the third Friday of the current month (6 means Friday, #3 means the current third), and 4#5 means the fifth Wednesday of the current month, assuming there is no fifth Wednesday in the current month, ignore and not trigger.
  • C: This character is only used in the date and week fields, representing the meaning of "Calendar". It means the date associated with the plan, if the date is not associated, it is equivalent to all dates in the calendar. For example, 5C in the date field is equivalent to the first day after the 5th of the calendar. 1C is equivalent to the first day after Sunday in the day of the week field.
  • cron expressions are not case sensitive.

2. Interface-based (dynamic)

1. Add dependencies

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.1</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

2. Add database records

Open the local database mysql, open the query window casually, and then execute the script content, as follows:

DROP DATABASE IF EXISTS `socks`;
CREATE DATABASE `socks`;
USE `SOCKS`;
DROP TABLE IF EXISTS `cron`;
CREATE TABLE `cron`  (
  `cron_id` varchar(30) NOT NULL PRIMARY KEY,
  `cron` varchar(30) NOT NULL  
);
INSERT INTO `cron` VALUES ('1', '0/5 * * * * ?');

insert image description here

Then add the data source in the application.properties file

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/socks?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

3. Create a timer

After the database is ready for data, we write a scheduled task. Note that the TriggerTask is added here. The purpose is to read the execution cycle we set in the database and execute the content of related scheduled tasks.
The specific code is as follows:

@Configuration      //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
public class DynamicScheduleTask implements SchedulingConfigurer {
    
    

    @Autowired
    private CronMapper cronMapper;

    /**
     * 执行定时任务.
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
    
    

        taskRegistrar.addTriggerTask(
                //1.添加任务内容(Runnable)
                () -> System.out.println("执行动态定时任务: " + LocalDateTime.now().toLocalTime()),
                //2.设置执行周期(Trigger)
                triggerContext -> {
    
    
                    //2.1 从数据库获取执行周期
                    String cron = cronMapper.selectByPrimaryKey("1").getCron();
                    //2.2 合法性校验.
                    if (StringUtils.isEmpty(cron)) {
    
    
                        // Omitted Code ..
                    }
                    //2.3 返回执行周期(Date)
                    return new CronTrigger(cron).nextExecutionTime(triggerContext);
                }
        );
    }

}

4. Start the test

Then open Navicat, modify the execution cycle to execute every 10 seconds, check the console, and find that the execution cycle has changed, and we don't need to restart the application, which is very convenient. As shown in the picture:

insert image description here

3. Quartz

Quartz is another open source project of the OpenSymphony open source organization in the field of Job scheduling. It can be combined with J2EE and J2SE applications or used alone. Quartz can be used to create simple or complex programs that run ten, hundreds, or even tens of thousands of Jobs.

1. Add dependencies

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

2. Write task class

package com.cn.service;
 
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class MyQuartz extends QuartzJobBean {
    
    
 
    private final Logger log = LoggerFactory.getLogger(MyQuartz.class);
 
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
    
    
        log.info("hello quartz");
    }
 
}

3. Write configuration class

package com.cn.config;

import com.cn.service.MyQuartz;
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class QuartzConfig {
    
    
 
    @Bean
    public JobDetail myQuartz() {
    
    
        return JobBuilder.newJob(MyQuartz.class).withIdentity("MyQuartz").storeDurably().build();
    }
 
    @Bean
    public Trigger studentRankQuartzTrigger() {
    
    
        return TriggerBuilder.newTrigger().forJob(myQuartz())
                .withIdentity("MyQuartz")
                .withSchedule(DailyTimeIntervalScheduleBuilder.dailyTimeIntervalSchedule().withInterval(5,		
                 DateBuilder.IntervalUnit.SECOND))
                .build();
    }
}

4. Start the project

Print "hello quartz" every 5 seconds

insert image description here

Guess you like

Origin blog.csdn.net/jiang_wang01/article/details/131466258