Spring Schedule Task动态改写Cron配置方式

目录
  • Spring Schedule Task动态改写Cron配置
    • Scheduling Tasks的常规使用
    • 动态改写Cron
  • @Scheduled定时任务动态修改cron参数
    • 先来看下Spring常规定时任务的配置
    • 下面来看看可以在不停服务的情况下动态修改任务周期的实现

Spring Schedule Task动态改写Cron配置

使用Spring @Scheduled标签可以很简单地定义Scheduled Task,但是有时我们需要在程序里动态地改写Cron的配置。

什么时候呢?

额,比如:

老板觉得Cron配置太难看了,想直接这样:10:15

Scheduling Tasks的常规使用

两个标签: @EnableScheduling, @Scheduled

@SpringBootApplication
@EnableScheduling
public class SchedulingTasksApplication {
 public static void main(String[] args) {
  SpringApplication.run(SchedulingTasksApplication.class);
 }
}
public class ScheduleTaskSimpleJob {
    @Scheduled(cron = "0 15 10 * * ?")
    public void scheduleCronTask() {
        long now = System.currentTimeMillis() / 1000;
        System.out.println(
        "schedule tasks using cron jobs - " + now);
    }
}

动态改写Cron

Implements SchedulingConfigurer就可以,想怎么改怎么改。
public class ScheduleTaskSimpleJob implements SchedulingConfigurer {
    public void scheduleCronTask() {
        long now = System.currentTimeMillis() / 1000;
        System.out.println(
        "schedule tasks using cron jobs - " + now);
    }
    @Override
 public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
  taskRegistrar.addTriggerTask(new Runnable() {
   @Override
   public void run() {
    scheduleCronTask();
   }
  }, new Trigger() {
   @Override
   public Date nextExecutionTime(TriggerContext triggerContext) {
    //TODO 将时间配置10:15转换为cron
    String cron = "0 15 10 * * ?";
    CronTrigger trigger = new CronTrigger(cron);
    Date nextExecDate = trigger.nextExecutionTime(triggerContext);
    return nextExecDate;
   }
  });
 }
}

@Scheduled定时任务动态修改cron参数

Spring框架自3.0版本起,自带了任务调度功能,好比是一个轻量级的Quartz,而且使用起来也方便、简单,且不需要依赖其他的JAR包。秉承着Spring的一贯风格,Spring任务调度的实现同时支持注解配置和XML配置两种方式。

再来谈谈变态的项目需求:我们正在做一个智能数字电表的数据采集项目,项目最终会在多个工业园上线,每个工业园对电表数据的采集周期可以进行自定义,例如A工业园想每10分钟采集一次数据,B工业园想每15分钟采集一次数据。因为数据采集是个重复的周期性工作,那么就可以考虑使用Spring框架的定时任务功能了。

按正常来讲,修改定时任务的执行周期还不简单,把服务停下来,改下任务的cron参数,再重启服务就搞定了。但有没有一种可能,在不停服务的情况下,就可以动态的修改任务的cron参数呢?完全是有可能的!

先来看下Spring常规定时任务的配置

如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:task="http://www.springframework.org/schema/task"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd ">

 <context:component-scan base-package="com.pes_soft.task.demo" />

 <!-- Spring注解方式配置调度任务 -->
 <task:executor id="executor" pool-size="3"/>
 <task:scheduler id="scheduler" pool-size="3"/>
 <task:annotation-driven executor="executor" scheduler="scheduler"/>
</beans>

注意:配置Spring定时任务时,需要在Spring配置文件的xml头部加入

xmlns:task="http://www.springframework.org/schema/task"和xsi:schemaLocation位置中加入

http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd

然后是注解式任务逻辑代码SpringStaticCronTask.java

package com.pes_soft.task.demo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Lazy(false)
@Component
public class SpringStaticCronTask {
 private static final Logger logger = LoggerFactory.getLogger(SpringStaticCronTask.class);

 @Scheduled(cron="0/5 * * * * ?")
 public void staticCronTask() {
  logger.debug("staticCronTask is running...");
        }
}

上述任务适用于具有固定任务周期的任务,若要修改任务执行周期,只能走“停服务→修改任务执行周期→重启服务”这条路。

下面来看看可以在不停服务的情况下动态修改任务周期的实现

步骤如下:

在定时任务类上增加@EnableScheduling注解,并实现SchedulingConfigurer接口。(值得注意的是:@EnableScheduling对Spring的版本要求比较高,一开始使用的3.2.6版本时一直未成功,后来改成4.2.5版本就可以了)

设置一个静态变量cron,用于存放任务执行周期参数。

另辟一线程,用于模拟实际业务中外部原因修改了任务执行周期。

设置任务触发器,触发任务执行,其中就可以修改任务的执行周期。

完整的SpringDynamicCronTask.java代码如下:

package com.pes_soft.task.demo;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
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 org.springframework.stereotype.Component;

@Lazy(false)
@Component
@EnableScheduling
public class SpringDynamicCronTask implements SchedulingConfigurer {
 private static final Logger logger = LoggerFactory.getLogger(SpringDynamicCronTask.class);
 private static String cron;
 public SpringDynamicCronTask() {
 cron = "0/5 * * * * ?";

  // 开启新线程模拟外部更改了任务执行周期
  new Thread(new Runnable() {
   @Override
   public void run() {
    try {
     Thread.sleep(15 * 1000);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }

    cron = "0/10 * * * * ?";
    System.err.println("cron change to: " + cron);
   }
  }).start();
 }

 @Override
 public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
  taskRegistrar.addTriggerTask(new Runnable() {
   @Override
   public void run() {
    // 任务逻辑
    logger.debug("dynamicCronTask is running...");
   }
  }, new Trigger() {
   @Override
   public Date nextExecutionTime(TriggerContext triggerContext) {
    // 任务触发,可修改任务的执行周期
    CronTrigger trigger = new CronTrigger(cron);
                Date nextExec = trigger.nextExecutionTime(triggerContext);
                return nextExec;
   }
  });
 }
}

将demo运行起来,查看任务执行情况,可以观察到任务的执行周期由5秒变成了10秒,期间服务并未停止。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • SpringBoot如何动态修改Scheduled(系统启动默认执行,动态修改)

    SpringBoot 动态修改Scheduled 场景: 可配置的 Scheduled 执行时间,正常的 Scheduled 是在项目启动的时候固定死的,没办法根据调用后台代码自动更新 Scheduled 执行时间 例如: 系统启动 读取时间 Cron : 0 0 3 * * ? ,通过执行后台方法 可以动态配置 Cron 时间格式,并且清楚掉原本执行任务,执行新的设置定时任务时间 1.根据 ThreadPoolTaskScheduler .ScheduledFuture 类 动态修改定时任务(

  • Spring的@Scheduled 如何动态更新cron表达式

    常见的本地定时写法如下: @Scheduled(cron = "0/5 * * * * ?") private void test() { log.info("业务处理逻辑...5秒一次"); } 如果想要动态更新cron表达式,可以这样写: 先写一个类,让cron表达式总是读成员变量的值. 再写一个controller,通过调用set方法就可以动态设置这个cron表达式了 @Lazy(false) @Component @EnableScheduling publ

  • springboot Quartz动态修改cron表达式的方法

    1.概述: 在开发中有的时候需要去手动禁止和启用定时任务,修改定时任务的cron表达式然后再让其动态生效,之前有过SSM的类似的业务的开发但是忘记写下来了...只好重新温习了一次,加上最近比较流行springBoot所以升级了一下用springBoot来完成. 2.关联技术 SpringBoot.Quartz.H2.thymeleaf (好像就这么多) 3.具体流程 1)首先去手动创建一个调度器工厂对象-SchedulerFactoryBean;其实应该不用手动创建的但是为了顾及到业务的复杂性所

  • spring schedule配置多任务动态cron(增删启停)

    一.背景 之前公司经常会遇到配置定时任务,简单的任务可以直接依赖spring. 简单任务直接使用 @scheduled 注解配合@EnableScheduling. 但是如何实现简单的动态cron呢? 开发原则: 尽可能在项目本身去实现,少依赖第三方框架,避免项目过于臃肿和复杂. 俩种任务调度方式: 二.本篇说明 springBoot 基础模块 spring-boot-starter-web 已经内置 schedule ,无需引入额外依赖. 先思考几个问题: 1.动态 cron 实现的原理 任务

  • Spring Schedule Task动态改写Cron配置方式

    目录 Spring Schedule Task动态改写Cron配置 Scheduling Tasks的常规使用 动态改写Cron @Scheduled定时任务动态修改cron参数 先来看下Spring常规定时任务的配置 下面来看看可以在不停服务的情况下动态修改任务周期的实现 Spring Schedule Task动态改写Cron配置 使用Spring @Scheduled标签可以很简单地定义Scheduled Task,但是有时我们需要在程序里动态地改写Cron的配置. 什么时候呢? 额,比如

  • 向Spring IOC 容器动态注册bean实现方式

    目录 本文的大纲 从一个需求谈起 Spring Bean的生命周期再完善 BeanDefinition Bean 加入IOC容器的几种方式 从spring容器中动态添加或移除bean 本文的大纲 从一个需求谈起 这周遇到了这样一个需求,从第三方的数据库中获取值,只是一个简单的分页查询,处理这种问题,我一般都是在配置文件中配置数据库的地址等相关信息,然后在Spring Configuration 注册数据量连接池的bean,然后再将数据库连接池给JdbcTemplate, 但是这种的缺陷是,假设填

  • spring boot使用sharding jdbc的配置方式

    本文介绍了spring boot使用sharding jdbc的配置方式,分享给大家,具体如下: 说明 要排除DataSourceAutoConfiguration,否则多数据源无法配置 @SpringBootApplication @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) public class Application { public static void main(String[] arg

  • spring schedule实现动态配置执行时间

    目录 spring schedule 动态配置执行时间 @schedule注解动态配置时间间隔 spring schedule 动态配置执行时间 之前saas平台实现动态修改定时任务的时间,都是通过xx-job这样的框架来实现,这样我们可以单独一个服务来管理我们整个saas平台的定时任务,但是最近给银行做的一个小项目,需要本地化部署,所以我不想弄很多的服务,并且他们并没有要求修改以后即时生效,所以我直接采用了 spring schedule结合mysql动态配置执行时间. 之前我们用的sched

  • Spring Task 动态修改任务执行计划cron方式

    目录 Spring Task 动态修改任务执行计划cron 原理 Demo如下 Spring @Scheduled定时任务动态修改cron参数 Spring Task 动态修改任务执行计划cron Spring Task 能够在不重启服务的情况下,动态修改批量任务执行时间. 原理 Spring Task目前仅支持TriggerContext上修改下次执行时间(批量任务执行后回调SchedulingConfigurer.configureTasks,让用户可以重新设置Trigger,从而动态修改下

  • SpringBoot定时任务两种(Spring Schedule 与 Quartz 整合 )实现方法

    前言 最近在项目中使用到定时任务,之前一直都是使用Quartz 来实现,最近看Spring 基础发现其实Spring 提供 Spring Schedule 可以帮助我们实现简单的定时任务功能. 下面说一下两种方式在Spring Boot 项目中的使用. Spring Schedule 实现定时任务 Spring Schedule 实现定时任务有两种方式 1. 使用XML配置定时任务, 2. 使用 @Scheduled 注解. 因为是Spring Boot 项目 可能尽量避免使用XML配置的形式,

  • Springboot自带定时任务实现动态配置Cron参数方式

    目录 Springboot自带定时任务实现动态配置Cron参数 SpringBoot定时任务的四种实现方式(主要) spring动态配置cron表达式,不需要停服 SchedulingConfigurer接口实现动态加载cron表达式 Springboot自带定时任务实现动态配置Cron参数 同学们,我今天分享一下SpringBoot动态配置Cron参数.场景是这样子的:后台管理界面对定时任务进行管理,可动态修改执行时间,然后保存入库,每次任务执行前从库里查询时间,以达到动态修改Cron参数的效

  • spring @schedule注解如何动态配置时间间隔

    目录 @schedule注解动态配置时间间隔 spring 注解式Schedule配置定时任务 @schedule注解动态配置时间间隔 动态配置时间间隔是通过自己实现的任务注册到任务调度实现的,并在每次调度的时候更改下次调度时间间隔,如果任务阻塞或者挂掉了就不会再被调度了,如果设置时间过长,到下次调度就需要等待很长时间. import org.springframework.beans.factory.annotation.Autowired; import org.springframewor

  • spring+apollo动态获取yaml格式的配置方式

    默认spring装载的都是.properties格式的配置文件,但是有时我们需要定义list或者map类型的配置,那么yaml就具有优势. 以下演示利用apollo来完成自动更新ip白名单的功能 1.重写配置工厂 public class YmlPropertySourceFactory extends DefaultPropertySourceFactory { public PropertySource<?> createPropertySource(String name, Encode

随机推荐