Spring定时器
Spring定时器
-
初始化Spring
在web.xml下的配置前端控制器的模块配置 load-on-startup 的值,使其大于0,保证项目启动的时候便能初始化Spring配置,如果不设置,就会导致定时器不执行,需要访问项目任意一个接口后才能执行<!--配置前端控制器--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--默认找/WEB-INF/[servlet的名称(springmvc)]-servlet.xml--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <!--初始化Spring配置--> <load-on-startup>1</load-on-startup> </servlet>
-
在spring-mvc 配置文件中引用 task 的约束,并配置定时器和注解驱动
<!--定时器配置--> <task:annotation-driven scheduler="myScheduler" /> <task:scheduler id="myScheduler" pool-size="5" />
-
在定时方法上配置定时注解,注意定时方法不能有参数
@Scheduled(cron = "0/5 * * * * ?") public void testSch1(){ System.out.println("执行1"); }
cron表达式的编写规则
cron表达式是一个字符串,以5个或者6个空格隔开,分为6个或者7个域,每一个域代表一个含义
cron的语法格式
- 秒 分 时 天 月 星期 年
- 秒 分 时 天 月 星期
- 秒:可以出现四种字符 “ , - * / ”,有效范围 0 - 59整数
- 分:可以出现四种字符 “ , - * / ”,有效范围 0 - 59整数
- 时:可以出现四种字符 “ , - * / ”,有效范围 0 - 23整数
- 天:可以出现八种字符 “ , - * / ? L W C ”,有效范围 0 - 31整数
- 月:可以出现四种字符“ , - * / ”,有效范围1-12整数或者 JAN - DEC
- 星期:可以出现八种字符“ , - * / ? L C # ”四个字符,有效范围为 1 - 7的整数或者 SUN - SAT,1 表示星期天,2 表示星期一,依次类推
- 年:可以出现“ , - * / ”四个字符,有效范围 1970 - 2099
每一个域都使用数字,但也可以出现如下特殊字符:
- *:匹配任意值,例如把 * 放在分钟上,指每分钟都执行
- ?:只能在天和星期两个域用,也是匹配任意值的,一般天用*,则星期用?,天用?,则星期用*
- -:表示范围,例如在分钟上使用 5 - 20,则表示从5分钟~20分钟,每分钟都触发一次
- /:表示起始时间开始出发,往后每个固定时间出发一次,例如在分钟上使用 5 / 20,则表示5分钟开始触发,之后每隔20分钟再触发一次
- ,:表示列出枚举类型,例如在分钟上使用 5,20,表示5分钟和20分钟分别触发一次
- L:表示最后,只能出现在星期和天上,例如在星期上使用 5L,表示最后一个星期四触发
- W:表示有效工作日(周一到周五),只能出现在天上,系统将会在离指定日期最近的工作日触发,例如5W,如果5号是星期六,则在星期五触发,如果5号是星期日,则在星期一触发,并且W找最近不会跨月
- LW:在天上使用,指某月的最后一个工作日
- #:指某个月第几个星期几,只能用在星期上,例如4#2,指某月的第二个星期三
Demo
每隔5秒执行一次:"*/5 * * * * ?"
每隔1分钟执行一次:"0 */1 * * * ?"
每天23点执行一次:"0 0 23 * * ?"
每天凌晨1点执行一次:"0 0 1 * * ?"
每月1号凌晨1点执行一次:"0 0 1 1 * ?"
每月最后一天23点执行一次:"0 0 23 L * ?"
每周星期天凌晨1点实行一次:"0 0 1 ? * L"
在26分、29分、33分执行一次:"0 26,29,33 * * * ?"
每天的0点、13点、18点、21点都执行一次:"0 0 0,13,18,21 * * ?"
表示在每月的1日的凌晨2点调度任务:"0 0 2 1 * ? *"
表示周一到周五每天上午10:15执行作业:"0 15 10 ? * MON-FRI"
表示2002-2006年的每个月的最后一个星期五上午10:15执行:"0 15 10 ? 6L 2002-2006"
注意: 由于"月份中的日期"和"星期中的日期"这两个元素互斥的,必须要对其中一个设置
秒 | 0-59 | , - * / |
---|---|---|
分 | 0-59 | , - * / |
时 | 0-23 | , - * / |
日 | 1-31 | , - * ? / L W C |
月 | 1-2或JAN-DEC | , - * / |
星期 | 1-7或SUN_SAT | , - * ? / L C # |
年 | 留空或1970-2099 | , - * / |
如果想要让定时器在项目启动之前就执行一次,可以让类实现 InitializingBean 接口,并重写 afterPropertiesSet 方法
import org.springframework.beans.factory.InitializingBean;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
@Controller
public class JsonController implements InitializingBean {
@Scheduled(cron = "0 0 0 1 * ?")
public void testSch1(){
System.out.println("执行1");
}
public void afterPropertiesSet() throws Exception {
this.testSch1();
}
}