业务场景描述:
定时任务的任务名称,cron(定时任务表达式),定时任务开关,存储在数据库表中。在不重启项目的情况下,修改定时任务表达式,可以实时获取新的定时任务执行时间规则;修改定时任务执行状态,可以随时开关定时任务。
使用技术:基于接口
SchedulingConfigurer
1、建表 管理定时任务
DROP TABLE IF EXISTS `scheduled`;
CREATE TABLE `scheduled` (
`name` varchar(20) DEFAULT NULL,
`cron` varchar(30) DEFAULT NULL,
`open` tinyint(1) DEFAULT NULL COMMENT '1开启, 其他为关闭'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of scheduled
-- ----------------------------
INSERT INTO `scheduled` VALUES ('demo1', '0/5 * * * * ?', '1');
INSERT INTO `scheduled` VALUES ('demo2', '0/6 * * * * ?', '1');
2、代码实现
定时任务配置类:
package com.example.demo.scheduled;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.springframework.context.annotation.Bean;
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.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
* @Description: 基于接口SchedulingConfigurer的动态定时任务
* @Author:
* @Date: 2020-08-27
@Configuration
@EnableScheduling
public abstract class ConfigurerSchedulingDemo implements SchedulingConfigurer {
//定时任务周期表达式
private String cron;
* @Description: 重写配置定时任务的方法
* @param: scheduledTaskRegistrar
* @return: void
* @Author:
* @Date: 2020/8/28
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.setScheduler(taskScheduler());
scheduledTaskRegistrar.addTriggerTask(
//执行定时任务
taskService();
//设置触发器
triggerContext -> {
cron = getCron();//获取定时任务周期表达式
CronTrigger trigger = new CronTrigger(cron);
return trigger.nextExecutionTime(triggerContext);
@Bean
public Executor taskScheduler() {
//设置线程名称
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();
//创建线程池
return Executors.newScheduledThreadPool(5, namedThreadFactory);
* @Description: 执行定时任务
* @param:
* @return: void
* @Author:
* @Date: 2020/8/28
public abstract void taskService();
* @Description: 获取定时任务周期表达式
* @param:
* @return: java.lang.String
* @Author:
* @Date: 2020/8/28
public abstract String getCron();
定时任务1
package com.example.demo.scheduled;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.dao.CronMapper;
import com.example.demo.entity.Scheduled;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import java.time.LocalDateTime;
* @Description:
* @Author:
* @Date: 2020-08-27
@Configuration
public class TaskDemo extends ConfigurerSchedulingDemo {
@Autowired //注入mapper
@SuppressWarnings("all")
CronMapper cronMapper;
@Override
public void taskService() {
Integer open = getOpen();
if (1== open){
System.out.println("定时任务demo1:"
+ LocalDateTime.now()+",线程名称:"+Thread.currentThread().getName()
+ " 线程id:"+Thread.currentThread().getId());
@Override
public String getCron() {
QueryWrapper<Scheduled> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name","demo1");
String cron = cronMapper.selectOne(queryWrapper).getCron();
return cron;
public Integer getOpen() {
QueryWrapper<Scheduled> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "demo1");
Integer open = cronMapper.selectOne(queryWrapper).getOpen();
return open;
定时任务2
package com.example.demo.scheduled;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.dao.CronMapper;
import com.example.demo.entity.Scheduled;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import java.time.LocalDateTime;
* @Description:
* @Author:
* @Date: 2020-08-27
@Configuration
public class TaskDemo1 extends ConfigurerSchedulingDemo {
@Autowired //注入mapper
@SuppressWarnings("all")
CronMapper cronMapper;
@Override
public void taskService() {
Integer open = getOpen();
if (1== open){
System.out.println("定时任务demo2:"
+ LocalDateTime.now()+",线程名称:"+Thread.currentThread().getName()
+ " 线程id:"+Thread.currentThread().getId());
@Override
public String getCron() {
QueryWrapper<Scheduled> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name","demo2");
String cron = cronMapper.selectOne(queryWrapper).getCron();
return cron;
public Integer getOpen() {
QueryWrapper<Scheduled> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "demo2");
Integer open = cronMapper.selectOne(queryWrapper).getOpen();
return open;
效果展示:
启动项目:控制台输出展示
修改数据库 demo1的执行时间为每15秒一次:
关闭demo1的定时任务,将demo1的open状态改为0:
业务场景描述:定时任务的任务名称,cron(定时任务表达式),定时任务开关,存储在数据库表中。在不重启项目的情况下,修改定时任务表达式,可以实时获取新的定时任务执行时间规则;修改定时任务执行状态,可以随时开关定时任务。使用技术:基于接口 SchedulingConfigurer1、建表 管理定时任务DROP TABLE IF EXISTS `scheduled`;CREATE TABLE `scheduled` ( `name` varchar(20) DEFAULT NULL,.
一. SchedulingConfigurer解析
Spring 中,创建定时任务除了使用@Scheduled 注解外,还可以使用 SchedulingConfigurer。既然两者都可以实现定时任务,那有什么不同呢?
@Schedule注解的一个缺点就是其定时时间不能动态更改,它适用于具有固定任务周期...
@Configuration
@EnableScheduling
public class CompleteScheduleConfig implements SchedulingConfigurer {
@Mapper
interface CornMapper{
@Select("select cron from cron limit 1")
@Component
@EnableScheduling
public class SftpScheduler implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
logger.info("
实现SchedulingConfigurer接口,并且重写configureTasks方法。
package cn.tongdun.spartan.biz.support.impl;
import cn.tongdun.spartan.biz.support.service.DockCustomerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factor
关于Springboot基于SchedulingConfigurer实现数据库动态执行多个定时任务总结
开发中遇到个需求,需要根据用户选择的季度或者月生成定时任务,当客户修改日期时,定时任务也要及时更新。
通常的定时任务是在下次执行时查询数据库,自动调整定时时间。
而这个因为间隔时间太长,等代码自动调整会出现问题(如年调整到月,会在本年年底执行定时任务时再调整,明显不符合需求)
所以根据网上查找的定时任务略微修改符合自己需求。
直接贴代码
package com.cm.property.scheduledT
之前在做oa项目的钉钉推送功能的时候,组长让我增加一个定时推送的功能,最好能实现用户在前端能自由修改时间。但是网上查了发现很多方法都需要重启项目才实现,后来从一篇博客上翻到说可以换一种思路,并不是去修改定时器时间,可以通过将之前的定时器停止注销,然后重新开启一个新的定时器来实现。
先上代码吧,基本上除了去掉了部分注入和方法参数的处理过程,整体逻辑都还是在的
* 钉钉消息推送定时器C...
CREATE TABLE `scheduled_task` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`task_key` varchar(128) NOT NULL COMMENT '任务key值(使用bean名称)',
`task_desc` varchar(128) DEFAULT NULL COMMENT '...
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
private ScheduledFuture<?> future;
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
retur
目录一、实现方法二、实现过程1.创建定时任务执行周期表(sys_cron)2.代码实现2.1创建spring boot项目,添加web、mybatis-plus、mysql相关依赖2.2 在项目中的application.yml 添加数据源2.3 创建定时器2.3.1 创建SysCron实体类2.3.2 创建CronMapper2.3.3 配置dao层包扫描2.3.4 配置定时任务2.4 启动项目,进行测试3.代码源码
在Spring Boot项目中,通过@EnableScheduling可启用Spring