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

mac2024-02-19  45

点击上方“后端技术精选”,选择“置顶公众号”

技术文章第一时间送达!

作者:yizhiwazi

www.jianshu.com/p/d160f2536de7

序言:创建定时任务非常简单,主要有两种创建方式:一、基于注解(@Scheduled) 二、基于接口(SchedulingConfigurer). 前者相信大家都很熟悉,但是实际使用中我们往往想从数据库中读取指定时间来动态执行定时任务,这时候基于接口的定时任务就大派用场了。

一、静态定时任务(基于注解)

基于注解来创建定时任务非常简单,只需几行代码便可完成。

@Scheduled 除了支持灵活的参数表达式cron之外,还支持简单的延时操作,例如 fixedDelay ,fixedRate 填写相应的毫秒数即可。

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

Cron表达式参数分别表示:

启动应用,可以看到控制台的信息如下:

诚然,使用Scheduled 确实很方便,但缺点是当我们调整了执行周期的时候,需要重启应用才能生效,这多少有些不方便。为了达到实时生效的效果,可以使用接口来完成定时任务。

二、动态定时任务(基于接口)

为了演示效果,这里选用 Mysql数据库 和 Mybatis 来查询和调整定时任务的执行周期,然后观察定时任务的执行情况。

1.引入依赖

    <!--依赖管理 -->     <dependencies>         <dependency><!--添加Web依赖 -->             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-web</artifactId>         </dependency>         <dependency><!--添加Mybatis依赖 -->             <groupId>org.mybatis.spring.boot</groupId>             <artifactId>mybatis-spring-boot-starter</artifactId>             <version>1.3.1</version>         </dependency>         <dependency><!--添加MySql依赖 -->             <groupId>mysql</groupId>             <artifactId>mysql-connector-java</artifactId>             <scope>runtime</scope>         </dependency>         <dependency><!--添加Test依赖 -->             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-test</artifactId>             <scope>test</scope>         </dependency>     </dependencies>

2.添加数据库记录

在Navicat 连接本地数据库,随便打开查询窗口,然后执行脚本内容,如下:

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

然后在项目中的application.yml 添加数据源:

#application.yml 配置如下: spring:   datasource:     url: jdbc:mysql://localhost:3306/socks?useSSL=false     username: root     password: root

3.创建定时器

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

@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);                 }         );     } }

4. 动态修改执行周期

启动应用后,查看控制台,打印时间是我们预期的每5秒一次:

然后打开Navicat ,将执行周期修改为每1秒执行一次,如图:

查看控制台,发现执行周期已经改变,并且不需要我们重启应用,十分方便。如图:

源码下载:

https://github.com/yizhiwazi/springboot-socks/tree/master/springboot-schedule-task

推荐阅读(点击即可跳转阅读)

5. 

Java笔记虾 认证博客专家 Spring MySQL Spring Boot 欢迎微信搜索【Java笔记虾】关注我的公众号,号内回复“后端面试”,送你一份精心准备的Java面试题(提纲+解析),后端技术精选每天定时推送优质Java技术博客,可以琐碎时间学点儿东西
最新回复(0)