在学到java的定时任务开发时用到spring的定时器,会涉及到cron表达式,这里参考其他资料,总结出cron表达式的规则。

cron表达式其实就是一个字符串,有2种语法格式。
  第一种是以6个空格隔开分7个域,其格式为Seconds Minutes Hours DayofMonth Month DayofWeek Year(秒 分 时 月中的第几天 月 一周的第几天 年)
  第二种是字符串以5个空格隔开分为6个域,其格式为Seconds Minutes Hours DayofMonth Month DayofWeek(秒 分 时 月中的第几天 月 一周的第几天)

每一个域代表一个含义,其取值范围如下:

字段

含义

允许值

范围

可能出现的特殊字符

Seconds


整数

0-59

", - * /"四个字符

Minutes


整数

0-59

", - * /"四个字符

Hours

小时

整数

0-23

", - * /"四个字符

DayofMonth

日期

整数

0-31(受月份限制)

", - * / ? L W C"八个字符

Month

月份

整数或指定字符

1-12或JAN-DEc

", - * /"四个字符

DayofWeek

星期

整数或指定字符

1-7或SUN-SAT

(1表示星期天,2表示星期一, 依次类推)

", - * / ? L C #"四个字符

Year(可选,留空)


整数

1970-2099

", - * /"四个字符

各个特殊字符的含义:

  (1)*:表示匹配该域的任意值,假如在Seconds域使用*, 即表示每秒执行一次。

  (2)?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和 DayofWeek会相互影响。例如想在每月的20日执行调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会执行,实际上并不是这样。——这个有歧义,待验证

  (3)-:表示范围,例如在Seconds域使用5-10,表示从5分到10分钟每秒执行一次

  (4)/:表示起始时间和每多少时间,例如在Seconds域使用5/10,则意味着第5秒钟执行一次,以后每10秒执行一次,也就是说在第5秒、第10秒、第15秒……执行。

注意:这个有歧义,每n秒和每隔n秒是不同意思的,但很多资料没区分,每隔n秒相当于每(n+1)秒,如每隔4秒相当于每5秒,如果是从0开始,就是第0秒、第5秒、第10秒等等。

  (5),:表示列出枚举值值。例如:在Seconds域使用5,15,则意味着在第5秒和第15秒执行一次。

  (6)L:表示最后,只能出现在DayofWeek和DayofMonth域,如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。

  (7)W: 表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一 到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份

  (8)LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。

  (9)#:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。

cron表达式范例:

每10秒执行一次:*/10 * * * * ?
   每分钟执行一次:0 */1 * * * ?
   每小时统计一次:0 0 */1 * * ?
   每天23点59分清理一次:0 59 23 * * ?

spring中Schedule定时器的使用

spring-task.xml配置文件如下(xmlns里带有多余的配置):

<?xml version="1.0" encoding="UTF-8"?>
<!-- xml 的头部 -->
<!-- 注意 .xsd 文件尽量不要带版本号 -->    
<beans xmlns="http://www.springframework.org/schema/beans"    
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     
    xmlns:tx="http://www.springframework.org/schema/tx"    
    xmlns:aop="http://www.springframework.org/schema/aop"    
    xmlns:context="http://www.springframework.org/schema/context"    
    xmlns:mvc="http://www.springframework.org/schema/mvc"  
    xmlns:task="http://www.springframework.org/schema/task"    
    xsi:schemaLocation="http://www.springframework.org/schema/beans       
    http://www.springframework.org/schema/beans/spring-beans.xsd       
    http://www.springframework.org/schema/tx       
    http://www.springframework.org/schema/tx/spring-tx.xsd     
    http://www.springframework.org/schema/aop    
    http://www.springframework.org/schema/aop/spring-aop.xsd     
    http://www.springframework.org/schema/context      
    http://www.springframework.org/schema/context/spring-context.xsd      
    http://www.springframework.org/schema/mvc    
    http://www.springframework.org/schema/mvc/spring-mvc.xsd  
    http://www.springframework.org/schema/task    
    http://www.springframework.org/schema/task/spring-task.xsd">  
    
    <task:annotation-driven /> <!-- 定时器开关-->   
    <!-- 这个bean对应的class是你编写了定时任务的java文件 -->
    <bean id="schedule" class="com.ccb.ic.mytask.Mytask"></bean>
    
</beans>

java测试实现代码如下:

package com.ccb.ic.mytask;

import java.util.Date;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component  //import org.springframework.stereotype.Component;
public class Mytask {
    public static void main(String[] args) {
        Mytask bean = new Mytask();
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "com/ccb/ic/mytask/spring-task.xml");
        System.out.println("1");
        bean.myTest();
        System.out.println("=================");
    }
    
    @Scheduled(cron="*/5 * *  * * ? ")   //每5秒执行一次
    public void myTest(){
        long tms = System.currentTimeMillis();
        Date date = new Date(tms);
        long h = date.getHours();
        long m = date.getMinutes();
        long s = date.getSeconds();
        String res = h + ":" + m + ":" + s;
        System.out.println(res);
    }
}

这两个文件放在maven工创建的同一个包下基本可以实现测试了。