0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

SpringBoot-动态定时任务调度

jf_78858299 来源:CSDN 作者:如约而至的重逢 2023-04-07 14:56 次阅读

一、业务场景

先说业务场景,根据用户输入的cron表达式进行定时调度,举个例子:如图

图片

根据用户输入的参数,生成表达式,然后定时去执行相应的业务逻辑。

二、Controller层(不是重点)

domain类

@TableName("sys_schedule")
@Data
public class Schedule {

    private static final long serialVersionUID = 1L;

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

    /**
     * 类型: 时间, 周, 日
     */
    @TableField("type")
    private Integer type;

    /**
     * time 时间
     */
    @TableField("day_time")
    private String dayTime;

    /**
     * time 周
     */
    @TableField("weekday")
    private String weekday;

    /**
     * time 日
     */
    @TableField("monthday")
    private String monthday;

    /**
     * 选中状态
     */
    @TableField("status")
    private Integer status;

    @TableField("cron")
    private String cron;

    @Override
    public String toString() {
        return "Schedule{" +
                "id=" + id +
                ", type=" + type +
                ", dayTime='" + dayTime + '\\'' +
                ", weekday='" + weekday + '\\'' +
                ", monthday='" + monthday + '\\'' +
                ", status=" + status +
                ", cron='" + cron + '\\'' +
                '}';
    }
}

controller方法

@Autowired
    private ScheduleService scheduleService;
 
  @PutMapping("/editItem")
    @ResponseBody
    public ResponseData editItem(Schedule schedule) {
        //ResponseData自己封装的响应结果
        //param是你前端传的,包含你的数据,如cron表达式
        this.scheduleService.update(schedule);
        return ResponseData.success();
    }

三、Service层

接口

public interface ScheduleService {

    /**
     * 更新
     * @Date 2020-12-25
     */
    void update(Schedule param);

    /**
     * 业务处理
     * @Date 2020-12-25
     */
    void work();

}

实现层

@Service
public class ScheduleServiceImpl implements ScheduleService {
    
 @Override
    public void update(Schedule param) {
  //这里简化了我自己的业务逻辑代码,根据公司自己需要来写即可
        //业务逻辑代码
        
        //思路就是:更新数据库的cron,类型等值,然后交给下面的定时工具类走定时方法
        this.scheduleMapper.updateById(param);
        String cron = param.getCron();
        //this就是你的业务执行service, 这里就是scheduleService
        ScheduleUtil.reset(new ScheduleTask(param.getId().toString(), this, null), cron);
    }
    
    @Override
    public void work() {
        //抓取数据的代码
        System.out.println("业务代码执行。。。");
    }

    
}

四、定时工具类

import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;

public class ScheduleUtil {

    private static ThreadPoolTaskScheduler threadPoolTaskScheduler = new    ThreadPoolTaskScheduler();
    private static Map<String, ScheduledFuture?> scheduledFutureMap = new HashMap<>();

    static {
        threadPoolTaskScheduler.initialize();
        System.out.println("定时任务线程池启动");
    }

    /**
     * 启动
     *
     * @param scheduleTask 定时任务
     * @param corn         执行时间表达式
     */
    public static boolean start(ScheduleTask scheduleTask, String corn) {
        System.out.println("启动定时任务线程 taskId " + scheduleTask.getId());
        ScheduledFuture? scheduledFuture = threadPoolTaskScheduler
                .schedule(scheduleTask, new CronTrigger(corn));
        scheduledFutureMap.put(scheduleTask.getId(), scheduledFuture);
        return true;
    }

    /**
     * 取消
     *
     * @param scheduleTask 定时任务
     */
    public static boolean cancel(ScheduleTask scheduleTask) {
        System.out.println("关闭定时任务线程 taskId " + scheduleTask.getId());
        ScheduledFuture? scheduledFuture =       scheduledFutureMap.get(scheduleTask.getId());
        if (scheduledFuture != null && !scheduledFuture.isCancelled()) {
            scheduledFuture.cancel(false);
        }
        scheduledFutureMap.remove(scheduleTask.getId());
        return true;
    }

    /**
     * 修改
     *
     * @param scheduleTask 定时任务
     * @param corn         执行时间表达式
     */
    public static boolean reset(ScheduleTask scheduleTask, String corn) {
        //先取消定时任务
        cancel(scheduleTask);
        //然后启动新的定时任务
        start(scheduleTask, corn);
        return true;
    }
}

五、工作线程

public class ScheduleTask implements Runnable {

    private static final int TIMEOUT = 30000;

    private String id;
    private ScheduleService service;

    public String getId() {
        return id;
    }

    /**
     * @param id      任务ID
     * @param service 业务类
     * @param keyword 关键字参数
     */
    public ScheduleTask(String id, ScheduleService service) {
        this.id = id;
        this.service = service;
    }

    @Override
    public void run() {
        //你自己的业务逻辑
        service.work();
    }
}

到这里结束了,这里主要是根据前台传的时间,进行生成cron,入库,执行定时任务。但是有一个问题,就是如果项目重启了的话,那么定时类那是无法加载到cron表达式的。那么接下来,加一个项目启动时,把数据库里的cron表达式重新灌入到定时类就可以。代码如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 项目启动时,加载
 * @Date: 2020/12/25:16:00
 **/
@Component
@Order(1)
public class initLineRunner implements CommandLineRunner {

    @Autowired
    private ScheduleService scheduleService;

    @Override
    public void run(String... args) throws Exception {
        System.out.println("init ........... ");
        //这里就是获取你数据库里的那个cron表达式
        Schedule param = scheduleService.get();
        String cron = param.getCron();
        ScheduleUtil.reset(new ScheduleTask(param.getId().toString(), scheduleService, null), cron);
    }
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:

https://blog.csdn.net/bbscz007/article/details/111695289

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 代码
    +关注

    关注

    30

    文章

    4597

    浏览量

    67332
  • spring
    +关注

    关注

    0

    文章

    334

    浏览量

    14208
  • SpringBoot
    +关注

    关注

    0

    文章

    172

    浏览量

    126
收藏 人收藏

    评论

    相关推荐

    Linux系统定时任务Crond

    会定期(默认每分钟检查一次)检查系统中是否有要执行的任务工作,如果有,便会根据其预先设定的定时任务规则自动执行该定时任务工作,这个crond定时任务服务就相当于我们平时早起使用的闹钟一
    发表于 07-05 06:22

    linux的循环定时任务

    linux循环定时任务
    发表于 05-20 14:59

    OPC 实时任务系统动态调度算法的研究与设计The Stud

    本文基于已有的OPC Server 实时任务模型,设计了处理混合任务集的动态调度算法(基于截止期优先)和实现方式。该算法实现了对混合任集可调度
    发表于 05-31 15:36 13次下载

    定时任务的发展史是怎么样的

    定时任务是互联网行业里最常用的服务之一,本文给大家介绍定时任务在我司的发展历程。 linux系统中一般使用crontab命令来实现,在Java世界里,使用最广泛的就是quartz
    发表于 07-18 17:38 0次下载
    <b class='flag-5'>定时任务</b>的发展史是怎么样的

    SpringBoot如何实现动态增删启停定时任务

    这两种方式不能动态添加、删除、启动、停止任务。 要实现动态增删启停定时任务功能,比较广泛的做法是集成Quartz框架。但是本人的开发原则是:在满足项目需求的情况下,尽量少的依赖其它框架
    的头像 发表于 09-24 09:49 2716次阅读
    <b class='flag-5'>SpringBoot</b>如何实现<b class='flag-5'>动态</b>增删启停<b class='flag-5'>定时任务</b>

    Python定时任务的实现方式

    调度模块schedule实现定时任务 利用任务框架APScheduler实现定时任务 Job 作业 Trigger 触发器 Executor 执行器 Jobstore 作业存储 Eve
    的头像 发表于 10-08 15:20 3289次阅读

    如何在SpringBoot项目中实现动态定时任务

    之前写过文章记录怎么在SpringBoot项目中简单使用定时任务,不过由于要借助cron表达式且都提前定义好放在配置文件里,不能在项目运行中动态修改任务执行时间,实在不太灵活。
    的头像 发表于 09-30 11:16 1587次阅读

    xxl-job任务调度中间件解决定时任务调度问题

    xxl-job是一款非常优秀的任务调度中间件,轻量级、使用简单、支持分布式等优点,让它广泛应用在我们的项目中,解决了不少定时任务调度问题。
    的头像 发表于 01-31 09:53 1265次阅读

    求一种SpringBoot定时任务动态管理通用解决方案

    SpringBoot定时任务的加强工具,实现对SpringBoot原生的定时任务进行动态管理,完全兼容原生@Scheduled注解,无需对
    的头像 发表于 02-03 09:49 627次阅读

    SpringBoot如何实现定时任务(下)

    SpringBoot创建定时任务的方式很简单,主要有两种方式:一、基于注解的方式(@Scheduled)二、数据库动态配置。实际开发中,第一种需要在代码中写死表达式,如果修改起来,又得重启会显得很麻烦;所以我们往往会采取第二种方
    的头像 发表于 04-07 14:51 1087次阅读
    <b class='flag-5'>SpringBoot</b>如何实现<b class='flag-5'>定时任务</b>(下)

    SpringBoot如何实现定时任务(上)

    SpringBoot创建定时任务的方式很简单,主要有两种方式:一、基于注解的方式(@Scheduled)二、数据库动态配置。实际开发中,第一种需要在代码中写死表达式,如果修改起来,又得重启会显得很麻烦;所以我们往往会采取第二种方
    的头像 发表于 04-07 14:51 1109次阅读
    <b class='flag-5'>SpringBoot</b>如何实现<b class='flag-5'>定时任务</b>(上)

    Spring Boot中整合两种定时任务的方法

    在 Spring + SpringMVC 环境中,一般来说,要实现定时任务,我们有两中方案,一种是使用 Spring 自带的定时任务处理器 @Scheduled 注解,另一种就是使用第三方
    的头像 发表于 04-07 14:55 1323次阅读
    Spring Boot中整合两种<b class='flag-5'>定时任务</b>的方法

    在Spring Boot中如何使用定时任务

    本文介绍在 Spring Boot 中如何使用定时任务,使用非常简单,就不做过多说明了。
    的头像 发表于 04-12 10:56 822次阅读

    如何动态添加修改删除定时任务

    如何动态添加修改删除定时任务?那么我们一起看看具体怎么实现,先看下本节大纲: (1)思路说明; (2)代码解析; (3)修改定时任务执行周期特别说明;
    的头像 发表于 04-12 11:06 918次阅读

    python定时任务实践

    由于程序需求,监测配置变化需要设置定时任务,每分钟执行一次,对任务持久化要求不高,不需要时可以关闭定时任务
    的头像 发表于 05-20 17:53 836次阅读
    python<b class='flag-5'>定时任务</b>实践