(九) spring boot 整合静态与动态定时器

关于在项目中的定时任务,我了解的不够深入,如果有兴趣可以去看下xxl-job,本篇仅仅介绍写在项目中的代码来实现定时任务的功能,分为两个方面,一个是静态,一个是动态。

实现定时器依赖的是spring封装好的@Schedule注解,通过这个注解我们来实现了定时任务的执行,所以我们不需要依赖的引入。

静态的定时器任务执行完全依赖注解,动态的则需要与数据库一起进行执行

静态定时器


在config包下添加配置类SimpleScheduleConfig

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.time.LocalDateTime;

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

直接启动项目,运行结果如下:

执行静态定时任务: 2019-11-30T16:21:40.011
执行静态定时任务: 2019-11-30T16:21:45.002
执行静态定时任务: 2019-11-30T16:21:50.001

动态定时器


在config包下添加配置类CompleteScheduleConfig

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
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
@EnableScheduling
public class CompleteScheduleConfig implements SchedulingConfigurer {

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

    @Autowired
    @SuppressWarnings("all")
    CronMapper cronMapper;

    /**
     * 执行定时任务.
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(
                //1.添加任务内容(Runnable)
                () -> System.out.println("执行定时任务2: " + 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);
                }
        );
    }
}

在数据库中添加数据表,并且添加数据

CREATE TABLE `cron`  (
  `cron_id` varchar(30),
  `cron` varchar(30) 
);
INSERT INTO `cron` VALUES ('1', '0/5 * * * * ?');

在这里插入图片描述
配置好数据库和配置类,就可以启动查看效果了

执行动态定时任务: 16:25:50.004
执行动态定时任务: 16:25:55.001
执行动态定时任务: 16:26:00.001

我们可以修改数据库的值来改变定时任务的执行频率为2s一次
在这里插入图片描述
代码运行会获得如下结果:

执行定时任务2: 16:28:28.002
执行定时任务2: 16:28:30.001
执行定时任务2: 16:28:32.002

cron定时表达式表达说明

cron一共有7位,但是最后一位是年,可以留空,所以我们可以写6位:

* 第一位,表示秒,取值0-59
* 第二位,表示分,取值0-59
* 第三位,表示小时,取值0-23
* 第四位,日期天/日,取值1-31
* 第五位,日期月份,取值1-12
* 第六位,星期,取值1-7,星期一,星期二...,注:不是第1周,第二周的意思
          另外:1表示星期天,2表示星期一。
* 第7为,年份,可以留空,取值1970-2099

一些特殊符号的含义:

(*)星号:可以理解为每的意思,每秒,每分,每天,每月,每年...
(?)问号:问号只能出现在日期和星期这两个位置,表示这个位置的值不确定,每天3点执行,所以第六位星期的位置,我们是不需要关注的,就是不确定的值。同时:日期和星期是两个相互排斥的元素,通过问号来表明不指定值。比如,1月10日,比如是星期1,如果在星期的位置是另指定星期二,就前后冲突矛盾了。
(-)减号:表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12
(,)逗号:表达一个列表值,如在星期字段中使用“1,2,4”,则表示星期一,星期二,星期四
(/)斜杠:如:x/y,x是开始值,y是步长,比如在第一位(秒) 0/15就是,从0秒开始,每15秒,最后就是0,15,30,45,60    另:*/y,等同于0/y

附表:

"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" 每年三月的星期三的下午2:10和2:44触发 
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发 
"0 15 10 15 * ?" 每月15日上午10:15触发 
"0 15 10 L * ?" 每月最后一日的上午10:15触发 
"0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发 
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发 
每隔5秒执行一次:*/5 * * * * ?
每隔1分钟执行一次:0 */1 * * * ?
每天23点执行一次:0 0 23 * * ?
每天凌晨1点执行一次:0 0 1 * * ?
每月1号凌晨1点执行一次:0 0 1 1 * ?
每月最后一天23点执行一次:0 0 23 L * ?
每周星期天凌晨1点实行一次:0 0 1 ? * L

crontab 表达式在线生成 http://cron.qqe2.com/

参考文章


springboot干货——(十五)整合定时任务schedule

SpringBoot 创建定时任务(配合数据库动态执行)

本系列文章


Banana的SpringBoot系列博客

(一) SpringBoot 项目初始化 + 配置swagger页面

(二) SpringBoot 整合 MyBatis-plus

(三) SpringBoot之使用Swagger配置详解

(四) spring boot 多环境配置

(五) spring boot 配置使用 redis

(六) spring boot 整合rabbitmq 与 rabbitmq使用教程

(七) spring boot 接口返回结果封装&&对象json的转换

(八) spring boot 整合异常封装

发布了129 篇原创文章 · 获赞 147 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq1515312832/article/details/103325867