SpringBoot设置动态定时任务(任务循环间隔时间可随意修改)

近两天因为工作需要,之前的项目架构更换,在新的架构上需要实现一个定时循环任务,如项目启动后每隔100秒执行一次,但是该间隔时间在项目运行中是必须可以动态修改的。

在网上搜了很多相关文章来看,几乎全都是运用cron表达式来实现的。但是cron表达式存在一个问题就是,它可以设置60秒以内,或者整分钟(或小时)来作为循环间隔,却无法实现每100秒(也就是大于59秒,但又不是整分钟)循环一次这样的需求。

当然cron表达式是一个很强大的工具,只是针对于该需求来说不是特别合适。cron表达式更适合于设置定时定点的任务,如几点几分去跑任务,每个小时的第几分钟去跑任务,每个月的某一天,或者每个星期的某一天的某个时间去跑任务等等,感兴趣的朋友可以搜一下cron表达式的规范去了解一下。

大体背景就是如上所说,接下来话不多说,直接上代码,代码中会为大家展示三种不同的设置以及它们的区别(包括使用cron表达式)

首先创建一个springboot项目,在启动类上加上扫描配置的注解 @ComponentScan

@SpringBootApplication
@ComponentScan
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}

接下来就是创建我们的服务类

需特别注意服务类上的两个注解 @Component 和 @EnableScheduling 必须配置

package com.example.demo.schedule;

import java.text.SimpleDateFormat;
import java.util.Date;

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.scheduling.support.PeriodicTrigger;
import org.springframework.stereotype.Component;

@Component
@EnableScheduling
public class ScheduleService implements SchedulingConfigurer {

	private String cron = "*/5 * * * * *";
	
	private long timer = 10000;
	
	private int count = 0;
	
	private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	@Override
	public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
		
		//方法1 动态使用cron表达式设置循环间隔
		taskRegistrar.addTriggerTask(new Runnable() {
			
			@Override
			public void run() {
				
				count += 1;
				
				//此处仅为模拟动态修改cron表达式,
                                //实际项目中可调用setCron(String cron)方法动态赋值
				if (count == 6) {
					cron = "*/" + 10 + " * * * * *";
					System.out.println("method 01 cron = --------->" + cron);
				}
				
				System.out.println(format.format(new Date()) + "============1111111111111111111111111111111111111");
			}
		}, new Trigger() {
			
			@Override
			public Date nextExecutionTime(TriggerContext triggerContext) {
				
				//此处使用CronTrigger触发器,可动态修改cron表达式来操作循环规则,
				//但是具体使用受制于cron表达式的规范,不能做到随心所欲设置循环间隔时间
				CronTrigger cronTrigger = new CronTrigger(cron);
				Date nextExecutionTime = cronTrigger.nextExecutionTime(triggerContext);
				
				return nextExecutionTime;
			}
		});
		
		//方法2 动态使用毫秒数设置循环间隔
		taskRegistrar.addTriggerTask(new Runnable() {
			
			@Override
			public void run() {
				
				count += 1;
				//此处仅为模拟动态修改timer,
                                //实际项目中可调用setTimer(long timer)方法动态赋值
				if (count == 6) {
					timer = 5000;
					System.out.println("method 02 timer = --------->" + timer);
				}
				System.out.println(format.format(new Date()) + "============222222222222222222222222222222222");
			}
		}, new Trigger() {
			
			@Override
			public Date nextExecutionTime(TriggerContext triggerContext) {
				
				//此处使用不同的触发器,为设置循环时间的关键,区别于CronTrigger触发器,
				//该触发器可随意设置循环间隔时间,单位为毫秒
				PeriodicTrigger periodicTrigger = new PeriodicTrigger(timer);
				Date nextExecutionTime = periodicTrigger.nextExecutionTime(triggerContext);
				
				return nextExecutionTime;
			}
		});
		
		//方法3 仅作为比较,
                //该方法循环间隔时间在项目启动时已定死,后续动态修改没有作用
		taskRegistrar.addFixedDelayTask(new Runnable() {
			
			@Override
			public void run() {
				
				count += 1;
				//此处仅为模拟动态修改timer,
                                //实际项目中可调用setTimer(long timer)方法动态赋值
				if (count == 6) {
					timer = 5000;
					System.out.println("method 03 timer = --------->" + timer);
				}
				System.out.println(format.format(new Date()) + "============3333333333333333333333333333333333333333");
			}
		}, timer);
	}

	public String getCron() {
		return cron;
	}

	public void setCron(String cron) {
		this.cron = cron;
	}

	public long getTimer() {
		return timer;
	}

	public void setTimer(long timer) {
		this.timer = timer;
	}
	
}

为了方便观察,我们先注释掉方法2和方法3,只开启方法1,启动项目观察结果,可以发现在cron表达式改变后,循环间隔时间也随着发生了变化

只启动方法2,观察结果,可以发现timer改变后,循环间隔时间也发生了变化,与方法1不同的是此处timer可以很方便的设置为非整分钟的数,如90秒,100秒等,而单个cron表达式无法实现该功能

只启动方法3,观察结果,可以发现更改timer并不能改变循环间隔时间,此方法的循环间隔在启动时已经定死,后续更改无效

扫码关注公众号“JAVA记录册”,免费领取超实用软件开发资料视频(包括大数据,前端完整视频,maven教程视频,java面试必备视频教程,Java并发视频教程)

该公众号致力于为大家分享工作中会用到一些简单实用的小知识,而不是那些悬在云端的高大上但又感觉空泛的文章,欢迎大家关注,谢谢!

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值