一、背景

在工作中,有些时候我们有些定时任务的执行可能是需要动态修改的,比如: 生成报表,有些项目配置每天的8点生成,有些项目配置每天的10点生成,像这种动态的任务执行时间,在不考虑分布式执行的情况下,我们可以
使用 Spring Task来简单的实现。

二、需求和实现思路

1、能够动态的添加一个定时任务。

Spring中存在一个类ThreadPoolTaskScheduler,它可以实现根据一个cron表达式来调度一个任务,并返回一个ScheduledFuture对象。

2、能够取消定时任务的执行。

通过调用上一步的ScheduledFuturecancel方法,就可以将这个任务取消。

3、动态的修改任务执行的时间。

  1. 先取消任务。
  2. 然后在重新注册一个任务。

4、获取定时任务执行的异常

ThreadPoolTaskScheduler类中有一个设置ErrorHandler的方法,给自己实现的ErrorHandler即可。

提示:

  1. Spring中我们通过@Scheduled注解来实现的定时任务,底层也是通过ThreadPoolTaskScheduler来实现的。可以通过ScheduledAnnotationBeanPostProcessor类来查看。

  2. ThreadPoolTaskScheduler的默认线程数是1,这个需要根据实际的情况进行修改。

三、代码实现

此处只给出动态注册定时任务和取消的定时任务的代码。

package com.huan.study.task.jobs.tasks;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronExpression;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; /**
* @author huan.fu 2021/7/8 - 下午2:46
*/
@Component
@Slf4j
public class DynamicCronTask implements InitializingBean { @Autowired
private ThreadPoolTaskScheduler taskScheduler; private ScheduledFuture<?> scheduledFuture; @Override
public void afterPropertiesSet() throws Exception {
// 动态启动一个定时任务
log.info("注册一个定时任务:每隔1秒执行一次");
scheduledFuture = register("* * * * * ?"); // 取消一个调度
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(5);
log.info("取消调度");
scheduledFuture.cancel(false);
log.info("取消结果:" + scheduledFuture.isCancelled());
log.info("重新注册一个定时任务:每隔2秒执行一次");
register("*/2 * * * * ?");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
} private ScheduledFuture<?> register(String cron) { // 高版本使用 CronExpression,低版本使用 CronSequenceGenerator
boolean validExpression = CronExpression.isValidExpression(cron);
log.info("cron:[{}]是合法的吗:[{}]", cron, validExpression); CronExpression expression = CronExpression.parse(cron);
LocalDateTime nextExecTime = expression.next(LocalDateTime.now());
if (null != nextExecTime) {
log.info("定时任务下次执行的时间为:[{}]", nextExecTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
} return taskScheduler.schedule(new Runnable() {
@Override
public void run() {
log.info("我执行了");
}
}, new CronTrigger(cron));
}
}

四、执行结果

五、完整代码

https://gitee.com/huan1993/spring-cloud-parent/tree/master/springboot/springboot-task

Spring动态添加定时任务的更多相关文章

  1. Quartz动态添加定时任务执行sql(服务启动添加+手动添加)

    系统用来每天插入视图数据... 一.数据库表设计 1.接口配置表(t_m_db_interface_config) 2.接口日志表(t_m_db_interface_log) 3.前端配置页面 查询页 ...

  2. elastic-job动态添加定时任务

    在elastic-job的使用过程中,我们会遇到动态添加定时任务的时候,但是官网上面并没有对这块内容进行说明.按照我的理解以及官网上面elastic-job的框架图,ej的定时任务其实是存储在zook ...

  3. 动态添加定时任务-quartz定时器

    Quartz动态添加.修改和删除定时任务 在项目中有一个需求,需要灵活配置调度任务时间,刚开始用的Java自带的java.util.Timer类,通过调度一个java.util.TimerTask任务 ...

  4. Celery 分布式任务队列快速入门 以及在Django中动态添加定时任务

    Celery 分布式任务队列快速入门 以及在Django中动态添加定时任务 转自 金角大王 http://www.cnblogs.com/alex3714/articles/6351797.html ...

  5. Celery动态添加定时任务

    背景 业务需求:用户可创建多个多人任务,需要在任务截止时间前一天提醒所有参与者 技术选型: Celery:分布式任务队列.实现异步与定时 django-celery-beat:实现动态添加定时任务,即 ...

  6. Spring+Quartz实现动态添加定时任务

    发布时间:2018-12-03   技术:spring4.0.2+quartz2.2.1   概述 在最近工作中,由于涉及到定时任务特别多,而这些工作又是由下属去完成的,在生成环境中经常会出现业务逻辑 ...

  7. spring动态添加bean

    不知道大家想过没有,我们使用mybatis的时候只要写接口和配置上一个sql语句就可以了,单从代码的角度来看,这是不合理的. 所以我们通常在service里面注入的mapper它其实是一个代理对象 ​ ...

  8. Spring Boot 创建定时任务(配合数据库动态执行)

    序言:创建定时任务非常简单,主要有两种创建方式:一.基于注解(@Scheduled) 二.基于接口(SchedulingConfigurer). 前者相信大家都很熟悉,但是实际使用中我们往往想从数据库 ...

  9. Quartz动态添加,修改,删除任务(暂停,任务状态,恢复,最近触发时间)

    首页 博客 学院 下载 图文课 论坛 APP 问答 商城 VIP会员 活动 招聘 ITeye GitChat 写博客 小程序 消息 登录注册 关闭 quartz_Cron表达式一分钟教程 09-05 ...

随机推荐

  1. Golang入门学习(二):控制分支

    文章目录 @[TOC] 1. 控制分支 1.1 if-else分支 1.2 switch分支 1.4 while 和do...while循环结构 1.5 多种循环结构 1.6 break 1.7 co ...

  2. [第七篇]——Docker Hello World之Spring Cloud直播商城 b2b2c电子商务技术总结

    Docker Hello World Docker 允许你在容器内运行应用程序, 使用  docker run 命令来在容器内运行一个应用程序. 输出Hello world xxx@xxx:~$ do ...

  3. NOIP模拟57

    前言 一整套都是水题(尽管 T4 稍有难度.. 从各位的分数上就可以看出来..Max 的 T1 打挂了,不然就有人 AK 了.. 感觉还好,最后还有 1h 看了看 T4 ,感觉有一点思路,就瞎 jb ...

  4. PHP密码散列算法的学习

    不知道大家有没有看过 Laravel 的源码.在 Laravel 源码中,对于用户密码的加密,使用的是 password_hash() 这个函数.这个函数是属于 PHP 密码散列算法扩展中所包含的函数 ...

  5. DISCUZ论坛添加页头及页尾背景图片的几种方法

    先给大家分享页头添加背景图片的两种方法:1. 第一种效果,是给discuz的整体框架添加背景图片,见图示: 添加方法如下:找到你现在使用模板common文件下的header.html文件,在<h ...

  6. Jmeter系类(31) - JSR223(1) | 控件介绍

    JSR233 介绍 JSR223控件执行JSR223脚本代码用于创建/更新所需的某些变量 JSR223可以使用其内置的变量,有助于精简脚本,提高开发测试的效率 由于JSR223脚本编译方式基本相同,J ...

  7. ubuntu中如何切换普通用户、root用户

    1.打开Ubuntu,输入命令:su root,回车提示输入密码,输入密码后提示:认证失败. 2.给root用户设置密码: 命令:sudo passwd root 输入密码,并确认密码. 3.重新输入 ...

  8. 『Python』matplotlib的imshow用法

    热力图是一种数据的图形化表示,具体而言,就是将二维数组中的元素用颜色表示.热力图之所以非常有用,是因为它能够从整体视角上展示数据,更确切的说是数值型数据. 使用imshow()函数可以非常容易地制作热 ...

  9. Dubbo管理平台搭建(duboo-admin-2.5.4)遇到的问题:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'uriBrokerService': Cannot create inner bean '(inner bean)' of type

    1.将dubbo的war包方式tomcat的webapps文件夹下,启动tomcat报错 错误信息如下: ERROR context.ContextLoader - Context initializ ...

  10. Java——多线程编程学习/01

    原文章:http://www.cnblogs.com/QG-whz/p/8351298.html  注:建议去看原博主的文章,单就这个知识点而论,比书本讲的透彻,如有违规,联系必删! 并发环境下进行编 ...