目录
在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.代码源码
点击此处可进行下载