点击上方“Java基基”,选择“设为星标”
做积极的人,而不是积极废人!
每天 14:00 更新文章,每天掉亿点点头发...
源码精品专栏
来源:blog.csdn.net/chenping1993/
article/details/108274814
业务场景描述:定时任务的任务名称,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');
推荐下自己做的 Spring Boot 的实战项目:
https://github.com/YunaiV/ruoyi-vue-pro
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:
*/
@Configuration
@EnableScheduling
public abstract class ConfigurerSchedulingDemo implements SchedulingConfigurer {
//定时任务周期表达式
private String cron;
/**
* @Description: 重写配置定时任务的方法
* @param: scheduledTaskRegistrar
* @return: void
* @Author:
*/
@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:
*/
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:
*/
@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:
*/
@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;
}
}
推荐下自己做的 Spring Cloud 的实战项目:
https://github.com/YunaiV/onemall
效果展示:
启动项目:控制台输出展示
修改数据库 demo1的执行时间为每15秒一次:
关闭demo1的定时任务,将demo1的open状态改为0:
- END -欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:
已在知识星球更新源码解析如下:
最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。
提供近 3W 行代码的 SpringBoot 示例,以及超 6W 行代码的电商微服务项目。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)