修改定时任务不重启项目,SpringBoot如何实现?

点击上方“Java基基”,选择“设为星标”

做积极的人,而不是积极废人!

每天 14:00 更新文章,每天掉亿点点头发...

源码精品专栏

 

来源:blog.csdn.net/chenping1993/
article/details/108274814

636a7fe439f5c58ec6f320564485b0bb.png


业务场景描述:定时任务的任务名称,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

效果展示:

启动项目:控制台输出展示

401fcb53b2e9368c03e526a9d72e31db.png

修改数据库 demo1的执行时间为每15秒一次:

8aeed5807b83c0484441c561687dea68.png

关闭demo1的定时任务,将demo1的open状态改为0:

c9dc564366d0c14ed015026c0e341d8e.png - END -

欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢

23eb4700b605c8590d1066941a831537.png

已在知识星球更新源码解析如下:

4c978e235cc86a946741e276e9dd96bc.png

f448ab98b1174f136cb1dae6170df46d.png

fdcab99301a758044c95b0f16b19a3c3.png

4ee402f49338cc03f8353c1241ef667a.png

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 6W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值