为何编译器不接受该Cron表达式?Bean初始化失败问题咨询
为什么Spring的@Scheduled不接受7字段的Cron表达式?
你遇到的这个异常原因很明确:Spring的@Scheduled注解只支持6字段的Cron表达式,而你配置的是7字段的格式。
先看一下错误提示里的关键信息:
Initialization of bean failed; nested exception is java.lang.IllegalStateException: Encountered invalid @Scheduled method 'refreshAlertWidowTable': Cron expression must consist of 6 fields (found 7 in "0 0 0 1 * ? *")
具体原因
我们平时常见的Cron表达式有两种格式:
- 7字段格式(带年份):秒 分 时 日 月 星期 年
- 6字段格式(不带年份):秒 分 时 日 月 星期
而Spring自带的@Scheduled注解只认6字段的格式,它不支持把年份作为第7个参数。你配置的0 0 0 1 * ? *最后多了一个年份字段(*),所以Spring会判定这是非法的表达式。
解决办法
有两种思路可以解决这个问题:
- 去掉年份字段:把配置改成
alert.widow.schedule=0 0 0 1 * ?,这就符合Spring的要求了,表达式的意思是「每月1号的凌晨0点整执行一次」,完全满足你原来的调度需求。 - 如果必须指定年份:Spring原生的
@Scheduled做不到,你可以引入Quartz框架,Quartz支持7字段的Cron表达式,不过需要额外配置Quartz的调度器和相关Bean,步骤会稍微复杂一点。
再贴一下你原来的代码片段方便对照:
@Scheduled(cron = "${alert.widow.schedule}") public void refreshAlertWidowTable() { widowService.findByActiveAndExclusion(true, false) .stream() .filter(w -> testAdult(w)) .collect(Collectors.toList()) .forEach(w -> this.save(new AlertWidow(w, false, LocalDateTime.now()))); }
内容的提问来源于stack exchange,提问作者Sarra




