Springboot定时任务实现动态设置

背景

在使用@Scheduled注解配置定时任务时,cron表达式一般写死在配置文件和代码中,不能根据业务或者环境的变化,进行灵活的变更,局限性很大。

本文围绕动态设置展开。

实现

配置文件
server:
  port: 8090

task:
  cron: 0/10 * * * * ?

这里配置一个默认的cron执行周期。

定时任务配置类
第一种实现

使用CronTrigger触发器,可动态修改cron表达式来操作循环规则

package com.lyu.scheduledtask.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * @Author: Lyu
 * @Description: 使用CronTrigger触发器,可动态修改cron表达式来操作循环规则
 * @Date: Created in 15:36 2022/11/14
 * @Modified By:
 */
@Component
public class ScheduledTaskCronTrigger implements SchedulingConfigurer {
    Logger LOGGER = LoggerFactory.getLogger(ScheduledTaskCronTrigger.class);

    @Value("${task.cron}")
    private String cron;

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

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(() -> {
            // 业务代码
            LOGGER.info("CronTrigger定时任务,currentTime:{},cron:{}", LocalDateTime.now().toString(), cron);
        }, triggerContext -> {
            // 使用CronTrigger触发器,可动态修改cron表达式来操作循环规则
            CronTrigger cronTrigger = new CronTrigger(cron);
            return cronTrigger.nextExecutionTime(triggerContext);
        });
    }
}

第二种实现

使用PeriodicTrigger触发器,可动态修改Timer来操作循环规则, 若周期时分秒执行,且数值大于进制,比如每71秒或65分或27小时执行,此时只能使用PeriodicTrigger。

package com.lyu.scheduledtask.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
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;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * @Author: Lyu
 * @Description: 使用PeriodicTrigger触发器,可动态修改cron表达式来操作循环规则:若周期时分秒执行,且数值大于进制,比如每71秒或65分或27小时执行
 * @Date: Created in 15:36 2022/11/14
 * @Modified By:
 */
@Component
public class ScheduledTaskPeriodicTrigger implements SchedulingConfigurer {
    Logger LOGGER = LoggerFactory.getLogger(ScheduledTaskPeriodicTrigger.class);

    private Long timer = 10000L;

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

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(() -> {
            // 业务代码
            LOGGER.info("PeriodicTrigger定时任务,currentTime:{},timer:{}", LocalDateTime.now().toString(), timer);
        }, triggerContext -> {
            // 使用不同的触发器,为设置循环时间的关键,区别于CronTrigger触发器,该触发器可随意设置循环间隔时间,单位为毫秒
            PeriodicTrigger periodicTrigger = new PeriodicTrigger(timer, TimeUnit.MILLISECONDS);
            return periodicTrigger.nextExecutionTime(triggerContext);
        });
    }
}

测试

再编写一个测试的接口

package com.lyu.scheduledtask.controller;

import com.lyu.scheduledtask.task.ScheduledTaskCronTrigger;
import com.lyu.scheduledtask.task.ScheduledTaskPeriodicTrigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @Author: Lyu
 * @Description:
 * @Date: Created in 15:53 2022/11/14
 * @Modified By:
 */
@RestController
@RequestMapping("/test")
public class ScheduledTaskController {

    @Autowired
    private ScheduledTaskCronTrigger scheduledTaskCronTrigger;

    @Autowired
    private ScheduledTaskPeriodicTrigger scheduledTaskPeriodicTrigger;


    @GetMapping(name = "设置定时时间", value = {"/updateCron"})
    public Object cron(@RequestParam("cron") String cron) {
        scheduledTaskCronTrigger.setCron(cron);

        return "设置成功";
    }

    @GetMapping(name = "设置定时时间", value = {"/updateTimer"})
    public Object timer(@RequestParam("timer") Long timer) {
        scheduledTaskPeriodicTrigger.setTimer(timer);
        return "设置成功";
    }


}

启动项目,分别调用两个设置执行时间的接口。

测试结果

默认配置的执行截图:
在这里插入图片描述
动态设置后的执行结果:
在这里插入图片描述
可以公众号一键三连,谢谢
在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值