赞
踩
定时任务调度,一句话概括就是:基于给定的时间点、给定的时间间隔、自动执行的任务(方法)。
Spring 3.0
以后自带了task
调度工具简单方便,(SpringBoot
项目里的主流实现方式)java
自带的API
java.util.Timer
类 java.util.TimerTask
类 (早期的实现方式)Quartz
开源框架,功能强大,但是使用起来稍显复杂。 (逐渐淘汰)@EnableScheduling
开启定时任务支持@EnableScheduling //开启定时任务支持
public class Application {
public static void main(String[] args) {
SpringApplication.run(AdminServerApplication.class,args);
}
}
@Component
public class ScheduledTask {
/**
* @Scheduled 表示这是一个需要定时执行的方法
* cron 表达式,用于设置每次执行的时间间隔
*/
@Scheduled( cron = "0/20 * * * * ? ") //配置时间规则:每20秒执行一次
public void scheduledMethod() throws ParseException {
//业务逻辑
System.out.println("定时任务执行");
}
}
Scheduled
注解源码:
package org.springframework.scheduling.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Repeatable(Schedules.class) public @interface Scheduled { String CRON_DISABLED = "-"; String cron() default ""; String zone() default ""; long fixedDelay() default -1L; String fixedDelayString() default ""; long fixedRate() default -1L; String fixedRateString() default ""; long initialDelay() default -1L; String initialDelayString() default "";
zone
:时区设置,可以设置为java.util.TimeZone
中的zoneId
,该字段一般留空即可
fixedDelay
:执行完一次以后(方法完全执行完之后)隔多长的时间再去执行
//执行完一次以后隔10000毫秒,即10秒再去执行
@Scheduled(fixedDelay = 10000)
fixedDelayString
:与fixedDelay
不同的就是只接收字符串,并且可以支持SpringEL
表达式来赋值
//执行完一次以后隔10000毫秒,即10秒再去执行
@Scheduled(fixedDelayString = "10000")
//SpringEL的赋值方式
@Scheduled(fixedDelayString = "${Schedul.fixedDelay}")
SpringEL
的赋值方式 需要在application.yml
中配置
Schedul:
fixedDelay: 10000
fixedRate
: 在上一次开始执行时间点(也就是方法刚开始执行的时候)之后多长时间再执行
//在上一次开始执行时间点(也就是方法刚开始执行的时候)的10000毫秒后,即10秒后再去执行
@Scheduled(fixedRate = 10000)
fixedRateString
:与fixedRate
不同的就是只接收字符串,并且可以支持SpringEL
表达式来赋值
//在上一次开始执行时间点(也就是方法刚开始执行的时候)的10000毫秒后,即10秒后再去执行
@Scheduled(fixedRate = "10000")
initialDelay
:设置第一次执行时的等待时间,即等待多长时间,再去执行第一次
//第一次延迟2秒后执行,之后就按只有fixedRate参数的方式每10秒执行一次
@Scheduled(initialDelay=2000, fixedRate=10000)
//第一次延迟2秒后执行,之后按只有fixedDelayStrin参数的方式每10秒执行一次
@Scheduled(initialDelay=2000, fixedDelayString=10000)
相当于initialDelay
也就只对定时任务的首次执行有效
initialDelayString
:与initialDelay
不同的就是只接收字符串,并且可以支持SpringEL
表达式来赋值
cron
表达式:用于设置每次执行的时间间隔
语法:[秒] [分] [小时] [日] [月] [周] [年]
其中[年]不是必须的域,通常使用的时候省略[年],前6位足以满足大部分需求,并且前6位也不能省。
cron
表达式支持的六个域 :
名称 | 是否必须 | 允许值 | 可以使用的通配符 |
---|---|---|---|
秒 | 是 | 0-59 | , - * / |
分 | 是 | 0-59 | , - * / |
时 | 是 | 0-23 | , - * / |
日 | 是 | 1-31 | , - * ? / L W C |
月 | 是 | 1-12 或 JAN-DEC | , - * / |
周 | 是 | 1-7 或 SUN-SAT | , - * ? / L C # |
年 | 否 | 1970-2099 | , - * / |
通配符说明:
*
代表任意值,表示当前域上的任意时间段都会触发
?
忽略当前域,它只能用在周和日两个域。因为二者会相互影响
-
区间连接符,表示时间范围。例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次
,
表示给当前域指定多个枚举值 (并列值)
/
表示起始时间开始触发,然后每隔固定时间触发一次
比如分钟上设置0/5表示,从第0分钟开始每5分钟执行一次,
L
即last
,表示最后的意思。表示当前域的最后一秒,最后一分钟执行,执行方式由所在域决定
W
表示在离当前日期最近的那个工作日触发,注意:是工作日
在日字段上置”15W”,表示离每月15号最近的那个工作日触发。
如果15号正好是周六,则找最近的周五(14号)触发,
如果15号是周日,则找最近的下周一(16号)触发
如果15号正好在工作日(周一至周五),则就在该天触发。
#
只能用在周这个域上面
比如5#2
表示在每月的第二个周五,如果指定的时间不存在则不会触发
LW
表示在本月的最后一个工作日触发
常见的使用示例:
每10秒执行一次:*/10 * * * * ? 每10分钟执行一次:0 */10 * * * ? 每天上午11:15触发:0 15 11 ? * * 或者 0 15 11 * * ? 在每天下午2点到下午2:59期间的每1分钟触发:0 * 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发:0 0/5 14 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发: 0 0/5 14,18 * * ? 每月5号8点执行一次:0 0 8 5 * ? 每月最后一天8点执行一次:0 0 8 L * ? 每月最后一周内的任意天数的1点执行一次:0 0 1 ? * L 在每小时的15分、17分、19分各执行一次:0 15,17,19 * * * ?
注:
对与Cron
表达式理解其含义即可
网上很多CRON
在线生成器,在实际项目应用中可以参考使用
/**
* 定时任务
*/
public class MyTimerTask extends TimerTask {
@Override
public void run() {
//定时任务执行体----里面可以编写定时任务需要执行的具体逻辑
System.out.println("定时任务执行!");
}
}
public class TimerTest {
public static void main(String[] args) {
Timer timer = new Timer(); //java定时器
//调用timer的schedule方法执行定时任务
//第二个参数为Long代表第一次延迟多久执行, 为Date代表第一次执行的具体时间是什么时候
//第三个参数为延迟执行时间,也就是每隔多久执行一次定时任务中的run方法,单位为毫秒
timer.schedule(new MyTimerTask(), startDate, 24 * 60 * 60 * 1000);
}
}
在Spring项目中使用java原生定时器通常会在项目启动时就开启定时任务
写法如下:
@Component public class TimerListener implements ApplicationListener<ContextRefreshedEvent> { private Timer timer = new Timer(); //java定时器 @Override public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) { //防止spring容器 和 springmvc容器导致此方法执行两次 //root application context 没有parent,他就是最顶层. if(contextRefreshedEvent.getApplicationContext().getParent() == null){ //需要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。 System.out.println("开启定时任务!"); //调用timer的schedule方法执行定时任务 //第二个参数为Long代表第一次延迟多久执行, 为Date代表第一次执行的具体时间是什么时候 //第三个参数为延迟执行时间,也就是每隔多久执行一次定时任务中的run方法,单位为毫秒 timer.schedule(new MyTimerTask(), startDate, 24 * 60 * 60 * 1000); } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。