Quartz中任意值*与不指定值?的区别

在Quartz定时任务的启动中,提示如下错误:

java.text.ParseException: Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.
    at org.quartz.CronExpression.buildExpression(CronExpression.java:511)
    at org.quartz.CronExpression.<init>(CronExpression.java:276)
    at org.quartz.impl.triggers.CronTriggerImpl.setCronExpression(CronTriggerImpl.java:347)
    at org.springframework.scheduling.quartz.CronTriggerFactoryBean.afterPropertiesSet(CronTriggerFactoryBean.java:243)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1625)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1562)
    ... 21 more

查看CRON表达式,定义如下:

<!-- CRON 顺序依次为秒,分钟,小时,日,月,周(星期几,从1开始星期天,7为星期六),年 -->
    <!-- ?仅可用于第4位日,与第6位周,表示不指定值,最多只能有一个 -->
    <!--  -->
    <bean id="computeSlaTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="computeSla"/>
        <!--  -->   
        <property name="cronExpression" value="0 0 0 * * 1 *"/>
    </bean>

在这里,涉及到“*”与“?”的区别,其定义如下:
1. “*”表示任意值,即在值的合理范围内(值域)都能执行,应有在日上的话,代表每一天都要执行任务;
2. “?”表示不指定值,即忽略此值的定义,也就是说不参与表达式的计算;

在这里,尤其要注意“?”,不参与计算的应用场景大部分都在发生冲突的情形,例如日(月中的天数)与周(周中的天数),在上面的例子中,我们无法要求月中的每天都是星期天(序数为1),所以这时日(第四位)应该不参与计算,正确的写法如下:

<bean id="computeSlaTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <property name="jobDetail" ref="computeSla"/>
    <!--  -->   
    <property name="cronExpression" value="0 0 0 ? * 1 *"/>
</bean>

结论

“?”代表不参与计算,只能出现在第4位“日”与第6位“周”,且最多只能在表达式中只能出现一次,否则无法确定唯一的时间,那么问题来了,怎么设置每个月的第几周?答案是采用“#”符,如“1#4”(第四周的星期天)。

当然这都不是最难的表达式,最难的在于“每个月的最后一个星期天”,“每年的最后一个星期天”,你能想出来吗?

猜你喜欢

转载自blog.csdn.net/yiifaa/article/details/78615162