一、背景

在工作中,有些时候我们有些定时任务的执行可能是需要动态修改的,比如: 生成报表,有些项目配置每天的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. TreeListLookUpEdit控件使用

    绑定数据 treeListLookUpEdit1.Properties.DataSource=list;增加列treeListLookUpEdit1.Properties.TreeList.Colum ...

  2. Java匿名内部类只可使用一次的理解

    匿名内部类只能使用一次,就不能在使用. 为了验证"只能使用一次"的实际含义,首先在程序中实例化了两个对象.并且在相应的类中加入了实现接口的匿名内部类: package com.An ...

  3. HCNP Routing&Switching之IS-IS邻居建立、LSDB同步、拓扑计算和路由形成

    前文我们了解了IS-IS的报文结构和类型相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15260670.html:今天我们来聊一聊IS-IS建立邻居. ...

  4. (5)java Spring Cloud+Spring boot+mybatis企业快速开发架构之SpringCloud-Spring Boot简介

    ​Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是简化新 Spring 应用的初始搭建以及开发过程.该框架使用了特定的方式进行配置,从而使开发人员不再需要定义样板化的配置 ...

  5. 【转】.net core开发windows服务

    .net core开发windows服务 文建Blog

  6. python多继承简单方法

    class people(object): #建创一个人类 def __init__(self,name,age): self.name = name self.age = age def eat(s ...

  7. 前端框架VUE——数据绑定及模板语法

    一.数据绑定 Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统: <div id="app"> {{ msg }} </di ...

  8. POJ1426——Find The Multiple

    POJ1426--Find The Multiple Description Given a positive integer n, write a program to find out a non ...

  9. springweb项目自定义拦截器修改请求报文头

    面向切面,法力无边,任何脏活累活,都可以从干干净净整齐划一的业务代码中抽出来,无非就是加一层,项目里两个步骤间可以被分层的设计渗透成筛子. 举个例子: 最近我们对接某银行接口,我们的web服务都是标准 ...

  10. Stream聚合函数

    Stream班介绍 幼稚园开学的第一天,各们家长把小朋友送到了园里,各位小朋友都你看看我,我看看你.有的嚎啕大哭,有的呆若木鸡....这里时候园长安排我拿来小本本记录入园的小朋友.... 记录小朋友 ...