spring,springboot自带定时任务设置动态定时任务

文章介绍了在Spring框架中,通过实现SchedulingConfigurer接口和继承ThreadPoolTaskScheduler来管理定时任务的方法,以及方案二的局限性——不支持一个类中同时调度多个独立的任务。
摘要由CSDN通过智能技术生成

方案一

1.实现SchedulingConfigurer 接口


import cn.hutool.core.date.LocalDateTimeUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
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;

import java.time.LocalDateTime;

@Data
@Slf4j
@Component
@EnableScheduling
public class ScheduleTask implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        // 动态使用cron表达式设置循环间隔
        //添加多个直接for循环即可
        taskRegistrar.addTriggerTask(() -> {
            //调用自己的定时任务
            log.info("Current time: {}", LocalDateTimeUtil.formatNormal(LocalDateTime.now()));
        }, (triggerContext) -> {
            // 使用CronTrigger触发器,可动态修改cron表达式来操作循环规则
            return new CronTrigger(Demo.cronMap.get("cron")).nextExecutionTime(triggerContext);
        });
    }


}

2.测试controller


import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@RequestMapping("/cpic/qwe")
@Controller
public class Demo implements InitializingBean{
    public static Map<String,String> cronMap = new HashMap<>();
    @Autowired
    private ScheduleTask scheduleTask;


   @GetMapping("updateTask")
    public void start(){
       System.out.println("修改定时任务表达式");
      cronMap.put("cron","0/5 * * * * ?");
   }

    @Override
    public void afterPropertiesSet() throws Exception {
       //假设这部分是从mysql数据库读取
        cronMap.put("cron","0/2 * * * * ?");
    }
}

方案2

第一步继承ThreadPoolTaskScheduler


import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.ScheduledMethodRunnable;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;

@Component
public class CustomTaskScheduler extends ThreadPoolTaskScheduler {


    private Map<Object, ScheduledFuture<?>> scheduledTasks = new IdentityHashMap<>();

    @Override
    public ScheduledFuture<?> schedule(Runnable task, Trigger trigger) {
        ScheduledFuture<?> future = super.schedule(task, trigger);
        this.putScheduledTasks(task, future);
        return future;
    }

    @Override
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period) {
        ScheduledFuture<?> future = super.scheduleAtFixedRate(task, period);
        this.putScheduledTasks(task, future);
        return future;
    }

    @Override
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Date startTime, long period) {
        ScheduledFuture<?> future = super.scheduleAtFixedRate(task, startTime, period);
        this.putScheduledTasks(task, future);
        return future;
    }

    private void putScheduledTasks(Runnable task, ScheduledFuture<?> future) {
        ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task;
        scheduledTasks.put(runnable.getTarget(), future);
    }

    public Map<Object, ScheduledFuture<?>> getScheduledTasks() {
        return scheduledTasks;
    }
}


第二步


import cn.hutool.core.date.LocalDateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.ScheduledMethodRunnable;
import org.springframework.stereotype.Controller;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import java.time.LocalDateTime;
@Slf4j
@RequestMapping("/cpic/qwe")
@Controller
public class Demo{
    @Autowired
    private CustomTaskScheduler customTaskScheduler;
    @Autowired
    private Demo demo;

    @RequestMapping("close")
    public void close(){
        customTaskScheduler.getScheduledTasks().get(demo).cancel(true);
    }

    @RequestMapping("open")
    public void open(){
        ScheduledMethodRunnable runnable = new ScheduledMethodRunnable(demo, ReflectionUtils.findMethod(demo.getClass(), "taskTest"));
        customTaskScheduler.schedule(runnable, new CronTrigger("*/5 * * * * *"));
    }

    @RequestMapping("open1")
    public void open1(){
        ScheduledMethodRunnable runnable = new ScheduledMethodRunnable(demo, ReflectionUtils.findMethod(demo.getClass(), "taskTest"));
        customTaskScheduler.schedule(runnable, new CronTrigger("*/7 * * * * *"));
    }

    public void taskTest(){
        System.out.println("测试定时任务:{}"+ LocalDateTimeUtil.formatNormal(LocalDateTime.now()));
    }

    public void taskTest1(){
        System.out.println("测试定时任务1:{}"+ LocalDateTimeUtil.formatNormal(LocalDateTime.now()));
    }
}

描述:方案二的缺点:暂时不支持一个类中存在多个定时任务,如果存在多个,去触发取消的时候
只能取消掉最后一个定时任务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值