Spring boot实现定时任务三:实现SchedulingConfigurer接口(动态定时任务)

在Spring Boot项目中,通过@EnableScheduling启用Spring自带的定时任务支持,在通过@Scheduled注解定义定时任务,但是通过注解只能编写固定时间的定时任务无法动态调整定时间隔可通过实现SchedulingConfigurer接口实现动态定时任务注册

一、实现方法

其实SchedulingConfigurer实现方法很简单,只需要实现SchedulingConfigurer并重写configureTasks方法,在启动类必须加上@EnableScheduling注解即可

二、实现过程

1.创建定时任务执行周期表(sys_cron)

在这里插入图片描述

2.代码实现

2.1创建spring boot项目,添加web、mybatis-plus、mysql相关依赖

<!--web-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.3</version>
</dependency>
<!--MySql驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

2.2 在项目中的application.yml 添加数据源


spring:
  # 数据源
  datasource:
      url: jdbc:mysql://localhost:3306/db_test?&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSl=false
      username: root
      password: root
      driver-class-name: com.mysql.jdbc.Driver

2.3 创建定时器

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

定时任务的执行周期需要从数据库中获取,所有首先配置sys_cron表的基本操作:

2.3.1 创建SysCron实体类
package com.example.schedulingconfigurerdemo.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;

/**
 * @author qzz
 */
@Data
@TableName("sys_cron")
public class SysCron implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 主键id
     */
    @TableId(value="id",type = IdType.AUTO)
    private Integer id;

    /**
     * cron执行表达式
     */
    @TableField("cron")
    private String cron;
}

2.3.2 创建CronMapper
package com.example.schedulingconfigurerdemo.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.schedulingconfigurerdemo.entity.SysCron;
import org.springframework.stereotype.Repository;

/**
 * @author qzz
 */
@Repository
public interface CronMapper extends BaseMapper<SysCron> {
}

2.3.3 配置dao层包扫描

配置文件配置扫描mapper.xml的路径:
在这里插入图片描述
启动类上添加@MapperSacn注解:

package com.example.schedulingconfigurerdemo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author qzz
 */
@SpringBootApplication
@MapperScan("com.example.schedulingconfigurerdemo.dao")
public class SchedulingConfigurerDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SchedulingConfigurerDemoApplication.class, args);
    }

}

2.3.4 配置定时任务
package com.example.schedulingconfigurerdemo.config;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.example.schedulingconfigurerdemo.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 java.util.Date;

/**
 * 基于接口SchedulingConfigurer的定时任务
 * 注解EnableScheduling:用于开启定时任务
 * @author qzz
 */
@Configuration
@EnableScheduling
public class ConfigurerSchedulingConfig implements SchedulingConfigurer {

    @Autowired
    private CronMapper cronMapper;


    /**
     * 重写配置定时任务的方法
     * @param scheduledTaskRegistrar
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {

        scheduledTaskRegistrar.addTriggerTask(
                //1.添加任务内容(Runnable)
                ()->{System.out.println("执行动态定时任务:"+new Date(System.currentTimeMillis())); }
                //2.设置执行周期(Trigger)
                ,triggerContext -> {
                    //2.1从数据库中获取执行周期
                    String cron = cronMapper.selectOne(null).getCron();
                    //System.out.println("数据库中获取的执行周期是:"+cron);
                    //2.2 合法性校验
                    if(StringUtils.isBlank(cron)){
                        //为空,设置默认值
                        cron = "0/5 * * * * ?";
                    }
                    //返回执行周期(Date)
                    return new CronTrigger(cron).nextExecutionTime(triggerContext);
                }

        );

    }


}

2.4 启动项目,进行测试

启动了springboot之后就会发现每次执行的时间差是数据库中设定的定时任务:
请添加图片描述
动态修改执行周期:
      修改数据库中的执行时间由每5秒执行一次修改成每秒执行一次。
在这里插入图片描述

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

3.代码源码

点击此处可进行下载

  • 6
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值