springBoot 定时任务 三种方式实现,cron

1、静态任务:基于注解

@Configuration      //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
public class SaticScheduleTask {
    //3.添加定时任务
    @Scheduled(cron = "0/5 * * * * ?")
    //或直接指定时间间隔,例如:5秒
    //@Scheduled(fixedRate=5000)
    private void configureTasks() {
        System.err.println("执行静态定时任务时间: " + LocalDateTime.now());
    }
}

Scheduled注解详解

概述

@Scheduled注解是Spring Boot提供的用于定时任务控制的注解,主要用于控制任务在某个指定时间执行,或者每隔一段时间执行。注意需要配合@EnableScheduling使用,@Scheduled主要有三种配置执行时间的方式:

  • cron
  • fixedRate
  • fixedDelay

cron

cron是@Scheduled的一个参数,是一个字符串,以5个空格隔开,只允许6个域(注意不是7个,7个直接会报错),分别表示秒、分、时、日、月、周

cron通配符

0-59

,- * /

0-59

,- * /

0-23

,- * /

1-31

,- * / ? L W

1-12

,- * / ?

1-7

,- * / ? L W

通配符含义

*

所有值,表示每秒、每月、每日、

不指定值,表示不关心,比如每日执行,那么周 就是 ? 不关心

-

表示区间,比如周的3-5 周三到周五都会执行

多个并列,日的2,13,14,就是2号,13日,14号,都会执行

/

表示“每” 秒的2/3,从2秒开始,每三秒触发一次执行

L

只允许用在周或者日上,表示最后,表示每月的最后一个什么,例如:日上 3L 表示这个月的倒数第三天,周上 3L 表示该月最后一个周四 L表示last最后的意思,7表示周六,(6表示周五,类推,1表示周日)

W

只允许在日上,表示举例最近的该日的工作日,(工作日 周一~周五)

#

只用在周上,表示每月的第几个周几,1#2,每月 的第2个周日,(1表示周日,7表示周六,注意外国日是周日是一个星期的第一天

cron生成器网站

在线Cron表达式生成器 - 码工具

fixedRate

fixedRate表示自上一次执行时间开始之后多长时间执行,以毫秒为单位。

fixedRateString

表示自上一次执行时间之后多长时间执行,以毫秒为单位,支持占位符。

   ##配置文件
interval=2000
 ##注解引用
@Scheduled(fixedRateStirng="${interval}")

fixedDelay

fixedDelay是自上一次执行时间结束之后多长时间执行,单位也是毫秒。

fixedDelayString

与fixedRateString类似,也是支持占位符

initialDelay

initialDelay表示首次延迟多长时间后执行,单位毫秒,首次执行之后,其他的执行计划,就按照其他的注解进行执行,也就是说,这个注解只在首次执行时生效。

initialDelayString

与initialDelay类似,不过是字符串,支持占位符。

2、动态任务:基于接口

需要导入mybatis依赖,springboot依赖,还有mysql依赖

<parent>
<!--   springboot -->
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
  <version>2.0.4.RELEASE</version>
</parent>

<!--添加Web依赖 -->
<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <!--添加MySql依赖 -->
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
  </dependency>
  <!--添加Mybatis依赖 配置mybatis的一些初始化的东西-->
  <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.1</version>
  </dependency>
</dependencies>

创建数据库

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 * * * * ?');

在项目的配置文件 中进行数据库的配置

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/数据库名字
    username: root
    password: root

创建定时器

数据库准备好数据后,开始编写定时任务,注意这里添加的是TriggerTask,目的是循环读取我们在数据库设置好的执行周期,以及执行相关定时任务的内容,具体代码如下:

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

    @Mapper
        public interface CronMapper {
            @Select("select cron from cron limit 1")
            public String getCron();
        }

    @Autowired      //注入mapper
    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.getCron();
                //2.2 合法性校验.
                if (StringUtils.isEmpty(cron)) {
                    // Omitted Code ..
                }
                //2.3 返回执行周期(Date)
                return new CronTrigger(cron).nextExecutionTime(triggerContext);
            }
        );
    }

}

3、基于多线程的定时任务

//@Component注解用于对那些比较中立的类进行注释;
//相对与在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释
@Component
@EnableScheduling   // 1.开启定时任务
@EnableAsync        // 2.开启多线程
public class MultithreadScheduleTask {
    @Async
    @Scheduled(fixedDelay = 1000)  //间隔1秒
    public void first() throws InterruptedException {
        System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
        System.out.println();
        Thread.sleep(1000 * 10);
    }
 
    @Async
    @Scheduled(fixedDelay = 2000)
    public void second() {
        System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
        System.out.println();
    }
}

多线程的 定时任务两个线程之间无相互影响。

猜你喜欢

转载自blog.csdn.net/qq_44431331/article/details/130190364