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

网友投稿 705 2023-03-23


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

序言:创建定时任务非常简单,主要有两种创建方式:一、基于注解(@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表达式参数分别表示:

秒(0~59) 例如0/5表示每5秒

分(0~59)

时(0~23)

月的某天(0~31) 需计算

月(0~11)

周几( 可填1-7 或 SUN/MON/TUE/WED/THU/FRI/SAT)

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

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

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

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

1.引入依赖

org.springframework.boot

spring-boot-starter-web

org.mybatis.spring.boot

mybatis-spring-boot-starter

1.3.1

mysql

mysql-connector-java

runtime

iKYYzVUy org.springframework.boot

spring-boot-starter-test

test

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秒执行一次,然后观察控制台打印效果:

可以清楚看到执行周期已经改变,并且不需要我们重启应用,十分方便。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java中BigDecimal的基本运算(详解)
下一篇:nuxt+axios解决前后端分离SSR的示例代码
相关文章

 发表评论

暂时没有评论,来抢沙发吧~