Java实现自动定时任务配置并判断当天是否需要执行示例

发布于:2024-06-26 ⋅ 阅读:(157) ⋅ 点赞:(0)

最近接到一个需求,用户要能配置一个定时循环的任务,就是和手机闹钟循环差不多,设置好比如周一、周二、周三,那么在这几天内这个任务就需要自动执行

需求不复杂,首先我需要判断当前是周几,当然用户说了让我看手机闹钟的循环规则,我看了下还有法定工作日和法定节假日这些
所以我们先写个工具类来判断当前日期是否需要执行

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.MonthDay;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author Sakura
 * @date 2024/6/20 9:48
 */
public class SchedulerTaskUtil {

    public enum RepeatCycle {
        DAILY,         // 每天
        MONTHLY,       // 每月
        HOLIDAYS,      // 法定节假日
        WORKDAYS,      // 法定工作日
        MONDAY,        // 周一
        TUESDAY,       // 周二
        WEDNESDAY,     // 周三
        THURSDAY,      // 周四
        FRIDAY,        // 周五
        SATURDAY,      // 周六
        SUNDAY         // 周日
    }

    private static final Set<MonthDay> HOLIDAYS = new HashSet<>();

    static {
        // 初始化法定节假日 2024 这个需要定期维护有些麻烦
        HOLIDAYS.add(MonthDay.of(1, 1));  // 元旦
        HOLIDAYS.add(MonthDay.of(2, 10)); // 春节
        HOLIDAYS.add(MonthDay.of(2, 11)); // 春节
        HOLIDAYS.add(MonthDay.of(2, 12)); // 春节
        HOLIDAYS.add(MonthDay.of(2, 13)); // 春节
        HOLIDAYS.add(MonthDay.of(2, 14)); // 春节
        HOLIDAYS.add(MonthDay.of(2, 15)); // 春节
        HOLIDAYS.add(MonthDay.of(2, 16)); // 春节
        HOLIDAYS.add(MonthDay.of(2, 17)); // 春节
        HOLIDAYS.add(MonthDay.of(4, 4)); // 清明节
        HOLIDAYS.add(MonthDay.of(4, 5)); // 清明节
        HOLIDAYS.add(MonthDay.of(4, 6)); // 清明节
        HOLIDAYS.add(MonthDay.of(5, 1)); // 劳动节
        HOLIDAYS.add(MonthDay.of(5, 2)); // 劳动节
        HOLIDAYS.add(MonthDay.of(5, 3)); // 劳动节
        HOLIDAYS.add(MonthDay.of(5, 4)); // 劳动节
        HOLIDAYS.add(MonthDay.of(5, 5)); // 劳动节
        HOLIDAYS.add(MonthDay.of(6, 8)); // 端午节
        HOLIDAYS.add(MonthDay.of(6, 9)); // 端午节
        HOLIDAYS.add(MonthDay.of(6, 10)); // 端午节
        HOLIDAYS.add(MonthDay.of(9, 15)); // 中秋节
        HOLIDAYS.add(MonthDay.of(9, 16)); // 中秋节
        HOLIDAYS.add(MonthDay.of(9, 17)); // 中秋节
        HOLIDAYS.add(MonthDay.of(10, 1)); // 国庆节
        HOLIDAYS.add(MonthDay.of(10, 2)); // 国庆节
        HOLIDAYS.add(MonthDay.of(10, 3)); // 国庆节
        HOLIDAYS.add(MonthDay.of(10, 4)); // 国庆节
        HOLIDAYS.add(MonthDay.of(10, 5)); // 国庆节
        HOLIDAYS.add(MonthDay.of(10, 6)); // 国庆节
        HOLIDAYS.add(MonthDay.of(10, 7)); // 国庆节
        // 其他假日可以继续添加
    }

    private Set<RepeatCycle> repeatCycles;

    public SchedulerTaskUtil(String repeatCyclesStr) {
        this.repeatCycles = Arrays.stream(repeatCyclesStr.split(","))
                .map(String::trim)
                .map(String::toUpperCase)
                .map(RepeatCycle::valueOf)
                .collect(Collectors.toSet());
    }

    public boolean shouldExecuteToday() {
        LocalDate today = LocalDate.now();
        DayOfWeek dayOfWeek = today.getDayOfWeek();
        MonthDay monthDay = MonthDay.from(today);

        if (repeatCycles.contains(RepeatCycle.DAILY)) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.MONTHLY) && today.getDayOfMonth() == 1) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.HOLIDAYS) && HOLIDAYS.contains(monthDay)) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.WORKDAYS) && !HOLIDAYS.contains(monthDay)
                && dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.MONDAY) && dayOfWeek == DayOfWeek.MONDAY) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.TUESDAY) && dayOfWeek == DayOfWeek.TUESDAY) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.WEDNESDAY) && dayOfWeek == DayOfWeek.WEDNESDAY) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.THURSDAY) && dayOfWeek == DayOfWeek.THURSDAY) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.FRIDAY) && dayOfWeek == DayOfWeek.FRIDAY) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.SATURDAY) && dayOfWeek == DayOfWeek.SATURDAY) {
            return true;
        }

        if (repeatCycles.contains(RepeatCycle.SUNDAY) && dayOfWeek == DayOfWeek.SUNDAY) {
            return true;
        }

        return false;
    }

    public static void main(String[] args) {
        // 示例:任务在周一和周三执行
        String repeatCyclesStr = "MONDAY,WEDNESDAY";
        SchedulerTaskUtil scheduler = new SchedulerTaskUtil(repeatCyclesStr);

        if (scheduler.shouldExecuteToday()) {
            System.out.println("Today is a repeat day, generate the task.");
            // 生成任务的逻辑
        } else {
            System.out.println("Today is not a repeat day.");
        }
    }
}

执行一下测试方法

在这里插入图片描述
显示今天不是需要重复的一天,因为今天星期四

在这里插入图片描述

给它加上周四

在这里插入图片描述

再执行就对了

在这里插入图片描述
剩下的就好说了,我们只需要加一个定时器就可以

import com.yokea.pro.task.mapper.TaskMapper;
import com.yokea.pro.task.model.po.Task;
import com.yokea.pro.task.util.SchedulerTaskUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author Sakura
 * @date 2024/06/20 15:24
 */
@Component
@EnableScheduling
@Slf4j
public class ScheduledTask {

//    每隔1分钟执行一次:0 */1 * * * ?
//    每天22点执行一次:0 0 22 * * ?
//    每月1号凌晨1点执行一次:0 0 1 1 * ?
//    每月最后一天23点执行一次:0 0 23 L * ?
//    每周周六凌晨3点实行一次:0 0 3 ? * L
//    在24分、30分执行一次:0 24,30 * * * ?

    @Autowired
    private TaskMapper taskMapper;


    /**
     * @description: 每天凌晨开始生成周期循环任务
     * @author: Sakura
     * @date: 2024/06/20 16:27
     */
    @Scheduled(cron = "0 0 0 * * ?") // 0 0 0 * * ? 每天0点启动
    @Async
    public void recurrentTasks() {
        log.info("定时生成周期循环任务程序启动——————————————————————————————————————————");
        try {
            // 先获取需要循环启动的周期任务
            List<Task> periodicTaskList = taskMapper.getPeriodicTaskList();
            for (Task task : periodicTaskList) {
                // 判断当前任务当天是否需要重复执行
                SchedulerTaskUtil schedulerTask = new SchedulerTaskUtil(task.getCycle());
                if (schedulerTask.shouldExecuteToday()) {
                    log.info("定时生成周期循环任务程序启动,任务ID:{}", task.getId());
                }
            }
        } catch (Exception e) {
            log.error("定时生成周期循环任务程序启动", e);
        }
    }


}

网站公告

今日签到

点亮在社区的每一天
去签到