关于java:Spring动态添加定时任务

16次阅读

共计 2427 个字符,预计需要花费 7 分钟才能阅读完成。

一、背景

在工作中,有些时候咱们有些定时工作的执行可能是须要动静批改的,比方: 生成报表,有些我的项目配置每天的 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

正文完
 0