页面通过配置执行周期和初次执行时间,后台根据这两个参数,生成对应的Cron表达式,定期生成执行任务的Task,当然,这里也可以直接使用Cron表达式插件,但是对使用者有一定的理解成本。
定义执行周期:
/**
* 执行周期枚举
*
* @author zhurunhua
* @since 2022/10/24 11:30
*/
public enum PeriodEnum {
/**
* 执行一次
*/
ONCE,
/**
* 每天
*/
DAILY,
/**
* 每周
*/
WEEKLY,
/**
* 每月
*/
MONTHLY
}
定义星期中英文枚举
/**
* 星期枚举
*
* @author zhurunhua
* @since 2022/10/24 11:30
*/
@Getter
public enum WeekEnum {
/**
* 周一
*/
Monday("星期一", "Mon"),
/**
* 周二
*/
Tuesday("星期二", "Tue"),
/**
* 周三
*/
Wednesday("星期三", "Wed"),
/**
* 周四
*/
Thursday("星期四", "Thu"),
/**
* 周五
*/
Friday("星期五", "Fri"),
/**
* 周六
*/
Saturday("星期六", "Sat"),
/**
* 周日
*/
Sunday("星期日", "Sun"),
;
private static final Map<String, WeekEnum> CODE_ROLE_MAP = new HashMap<>();
private static final Map<String, WeekEnum> NAME_ROLE_MAP = new HashMap<>();
static {
for (WeekEnum type : WeekEnum.values()) {
NAME_ROLE_MAP.put(type.name, type);
CODE_ROLE_MAP.put(type.code, type);
}
}
private final String name;
private final String code;
WeekEnum(final String name, final String code) {
this.name = name;
this.code = code;
}
/**
* to WeekEnum by code.
*
* @param code code
* @return WeekEnum
*/
public static WeekEnum codeOf(final String code) {
if (StringUtils.isBlank(code)) {
return Sunday;
}
WeekEnum matchType = CODE_ROLE_MAP.get(code);
return Objects.isNull(matchType) ? Sunday : matchType;
}
/**
* to WeekEnum by name.
*
* @param name name
* @return WeekEnum
*/
public static WeekEnum nameOf(final String name) {
if (Strings.isNullOrEmpty(name)) {
return Sunday;
}
WeekEnum matchType = NAME_ROLE_MAP.get(name);
return Objects.isNull(matchType) ? Sunday : matchType;
}
cron表达式模板常量:
/**
* cron表达式模板
*
* @author zhurunhua
* @since 2022/10/24 11:50
*/
public interface CronPatternConstant {
/**
* 执行单次cron表达式模板
* eg: 59 59 23 1 12 ? 2022 (2022-12-01 23:59:59执行一次)
*/
String ONCE_CRON_PATTERN = "%s %s %s %s %s ? %s";
/**
* 每天执行cron表达式模板
* eg: 59 59 23 * * ? (每日23:59:59执行)
*/
String DAILY_CRON_PATTERN = "%s %s %s * * ?";
/**
* 每周执行cron表达式模板
* eg: 59 59 23 ? * Fri (每周五23:59:59执行)
*/
String WEEKLY_CRON_PATTERN = "%s %s %s ? * %s";
/**
* 每月执行cron表达式模板
* eg: 59 59 23 8 * ? (每月8号23:59:59执行)
*/
String MONTHLY_CRON_PATTERN = "%s %s %s %s * ?";
}
/**
* Cron表达式工具类
*
* @author zhurunhua
* @since 2022/10/24 11:46
*/
@Slf4j
public enum GenerateCronUtil {
/**
* 单例
*/
INSTANCE;
private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private final SimpleDateFormat weekFormat = new SimpleDateFormat("E");
/**
* 根据执行周期和初次执行时间,生成cron表达式
*
* @param period 执行周期
* @param beginTime 初次执行时间
* @return cron表达式
*/
public String generateCronByPeriodAndTime(PeriodEnum period, String beginTime) {
Date parsedDate;
try {
parsedDate = dateFormat.parse(beginTime);
} catch (ParseException e) {
log.error("parse time error. [time]: {}", beginTime);
return "";
}
String[] dateAndTime = beginTime.split(" ");
String date = dateAndTime[0];
String time = dateAndTime[1];
String[] splitDate = date.split("-");
String year = splitDate[0];
String month = splitDate[1];
String day = splitDate[2];
String[] splitTime = time.split(":");
String hour = splitTime[0];
String minute = splitTime[1];
String second = splitTime[2];
String cron = "";
switch (period) {
case ONCE:
cron = String.format(CronPatternConstant.ONCE_CRON_PATTERN, second, minute, hour, day, month, year);
break;
case DAILY:
cron = String.format(CronPatternConstant.DAILY_CRON_PATTERN, second, minute, hour);
break;
case WEEKLY:
String week = weekFormat.format(parsedDate);
String weekCode = WeekEnum.nameOf(week).getCode();
cron = String.format(CronPatternConstant.WEEKLY_CRON_PATTERN, second, minute, hour, weekCode);
break;
case MONTHLY:
cron = String.format(CronPatternConstant.MONTHLY_CRON_PATTERN, second, minute, hour, day);
break;
default:
break;
}
return cron;
}
}
public class Test {
public static void main(String[] args) throws ParseException {
String time = "2022-12-01 12:00:00";
String onceCron = GenerateCronUtil.INSTANCE.generateCronByPeriodAndTime(PeriodEnum.ONCE, time);
String dailyCron = GenerateCronUtil.INSTANCE.generateCronByPeriodAndTime(PeriodEnum.DAILY, time);
String weeklyCron = GenerateCronUtil.INSTANCE.generateCronByPeriodAndTime(PeriodEnum.WEEKLY, time);
String monthlyCron = GenerateCronUtil.INSTANCE.generateCronByPeriodAndTime(PeriodEnum.MONTHLY, time);
System.out.println("单次执行cron:" + onceCron);
System.out.println("每天执行cron:" + dailyCron);
System.out.println("每周执行cron:" + weeklyCron);
System.out.println("每月执行cron:" + monthlyCron);
}
}
输出:
单次执行cron:00 00 12 01 12 ? 2022
每天执行cron:00 00 12 * * ?
每周执行cron:00 00 12 ? * Thu
每月执行cron:00 00 12 01 * ?