As we develop projects, we often need timed tasks to help us do something. Spring Boot does this by default, just add annotations

1. Annotation-based (static)

1. Pom package configuration

You only need to import the Spring Boot Starter package to the POM package

  <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>
Copy the code

2. Create a scheduled task implementation class

Scheduled Task 1:

@Configuration
@EnableScheduling
public class SchedulerTask {

    private int count=0;

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

Scheduled Task 2:

@Configuration
@EnableScheduling
public class Scheduler2Task {

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

    @Scheduled(fixedRate = 6000)
    public void reportCurrentTime(a) {
        System.out.println("Present time:" + dateFormat.format(newDate())); }}Copy the code

The results are as follows:

this is scheduler task runing  0Present Time: 09:44:17
this is scheduler task runing  1Present Time: 09:44:23
this is scheduler task runing  2Present Time: 09:44:29
this is scheduler task runing  3Present Time: 09:44:35
Copy the code

Parameters that

@Configuration is used to mark Configuration classes and has the effect of a Component.

@enablescheduling The scheduled task is enabled

The @scheduled parameter accepts two Scheduled Settings, one of which is the usual cron=”*/6 * * * *?” , one is fixedRate = 6000, and both mean that the content is printed every six seconds.

FixedRate instructions

  • @Scheduled(fixedRate = 6000) : Execution is Scheduled 6 seconds after the last time it started

  • @scheduled (fixedDelay = 6000) : Scheduled is executed 6 seconds after the last time point

  • @Scheduled(initialDelay=1000, fixedRate=6000) : Scheduled(initialDelay=1000, fixedRate=6000) : Executed after the first delay of 1 second and then every 6 seconds according to fixedRate’s rules

The cron property, which specifies a task execution rule in the form of an expression, is also timed from the completion of the last task. The expression rules are as follows:

The rules for each position are as follows:

Remark:

  • The asterisk (*) is used in all fields to indicate each moment in the corresponding time domain. For example, the asterisk (*) in the minute field indicates every minute.
  • Question mark : This character is only used in the date and week fields and is usually specified as a “meaningless value”, which is equivalent to a placeholder.
  • The minus sign (-) indicates a range. For example, if “10-12” is used in the hour field, the range is from 10 to 12, that is, 10,11,12.
  • Comma (,) : indicates a list value. For example, if “MON,WED,FRI” is used in the week field, it indicates Monday, Wednesday, and Friday.
  • Slash (/) : x/y expresses a sequence of equal step sizes, where x is the starting value and y is the incremental step size. If you use 0/15 in seconds, it means 0,15,30, and 45 seconds, while 5/15 in minutes means 5,20,35, and 50. You can also use */y, which is the same as 0/y.
  • L: This character is only used in the date and week fields and stands for “Last”, but it has a different meaning in the two fields. L In the date field, indicates the last day of the month, such as the 31st day of January or the 28th day of February in a non-leap year. If L is used during the week, it means Saturday, which is the same as 7. However, if L appears in the week field and is preceded by a numerical value X, it means “the last X day of the month.” For example, 6L means the last Friday of the month.
  • W: This character can only appear in the date field. It modifies the leading date and indicates the working day closest to the date. For example, 15W indicates the closest working day to the 15th of the month. If the 15th of the month falls on a Saturday, Friday the 14th is matched. If the 15th falls on a Sunday, it matches Monday the 16th; If the 15th is Tuesday, it turns out to be Tuesday the 15th. If you specify 1W, if the 1st is a Saturday, the result will be Monday the 3rd, not the last day of the last month. The W string can only specify a single date, not a range of dates.
  • LW combination: You can combine LW in the date field, which means the last business day of the month.
  • Pound sign (#) : This character can only be used in the week field to indicate a day of the month. For example, 6#3 indicates the third Friday of the month (6 indicates Friday, #3 indicates the current third), and 4#5 indicates the fifth Wednesday of the month. If there is no fifth Wednesday in the month, ignore the trigger.
  • C: This character is only used in the date and week fields and represents the meaning of “Calendar”. It means the date to which the plan is associated, or if the date is not associated, all dates in the calendar. For example 5C in the date field corresponds to the first day after the 5th day of the calendar. 1C in the week field corresponds to the day after Sunday.
  • Cron expressions are case insensitive.

2. Interface based (dynamic)

1. Pom package configuration

<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.31.</version>
</dependency>

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

2, add database record:

Start mysql, open the query window randomly, and execute the script 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 * * * * ?');
Copy the code

Then add the data source to 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
Copy the code

3. Create a timer

After the database is ready, we write the scheduled task. Note that the TriggerTask is added to read the cycle of execution that we have set up in the database, as well as to execute the related scheduled task. The specific code is as follows:

package com.cn.service;

import com.cn.dao.CronMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

@Configuration      //1. Mainly used to mark configuration classes, with the effect of Component.
@EnableScheduling   // 2. Enable the scheduled task
public class DynamicScheduleTask implements SchedulingConfigurer {

    @Autowired
    private CronMapper cronMapper;

    /** * Performs scheduled tasks. */
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {

        taskRegistrar.addTriggerTask(
                //1. Add task content (Runnable)
                () -> System.out.println("Execute a dynamic scheduled task:" + LocalDateTime.now().toLocalTime()),
                //2. Set the execution cycle (Trigger)
                triggerContext -> {
                    //2.1 Obtain the execution period from the database
                    String cron = cronMapper.selectByPrimaryKey("1").getCron();
                    2.2 Validity verification.
                    if (StringUtils.isEmpty(cron)) {
                        // Omitted Code ..
                    }
                    //2.3 Return to Execution Period (Date)
                    return newCronTrigger(cron).nextExecutionTime(triggerContext); }); }}Copy the code

4. Start the test

Then open Navicat, change the execution cycle to every 10 seconds, look at the console and see that the execution cycle has changed and we don’t need to restart the application, which is very convenient. As shown in figure:

Third, Quartz

Quartz is another open source project in the Job Scheduling area from the OpenSymphony open source organization, and it can be used in combination with J2EE and J2SE applications or on its own. Quartz can be used to create programs as simple or complex as running 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>
Copy the code

2. Write task classes

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"); }}Copy the code

3. Write configuration classes

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(a) {
        return JobBuilder.newJob(MyQuartz.class).withIdentity("MyQuartz").storeDurably().build();
    }
 
    @Bean
    public Trigger studentRankQuartzTrigger(a) {
        return TriggerBuilder.newTrigger().forJob(myQuartz())
                .withIdentity("MyQuartz")
                .withSchedule(DailyTimeIntervalScheduleBuilder.dailyTimeIntervalSchedule().withInterval(5, DateBuilder.IntervalUnit.SECOND)) .build(); }}Copy the code

4. Start the project

Print “Hello Quartz” every 5 seconds