SpringBoot下的定时任务调度@Scheduled,Java原生定时任务
一、概述
定时任务调度,一句话概括就是:基于给定的时间点、给定的时间间隔、自动执行的任务(方法)。
二、java生态下的定时任务实现方式
Spring 3.0
以后自带了task
调度工具简单方便,(SpringBoot
项目里的主流实现方式)java
自带的API
java.util.Timer
类java.util.TimerTask
类 (早期的实现方式)Quartz
开源框架,功能强大,但是使用起来稍显复杂。 (逐渐淘汰)
三、SpringBoot项目里的定时器主流实现方式
3.1 SpringBoot引导类了上加上@EnableScheduling
开启定时任务支持
@EnableScheduling //开启定时任务支持
public class Application {
public static void main(String[] args) {
SpringApplication.run(AdminServerApplication.class,args);
}
}
3.2 在引导类的包及其子包下编写定时任务类
@Component
public class ScheduledTask {
/**
* @Scheduled 表示这是一个需要定时执行的方法
* cron 表达式,用于设置每次执行的时间间隔
*/
@Scheduled( cron = "0/20 * * * * ? ") //配置时间规则:每20秒执行一次
public void scheduledMethod() throws ParseException {
//业务逻辑
System.out.println("定时任务执行");
}
}
3.3 Scheduled注解的各个参数解析
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
在线生成器,在实际项目应用中可以参考使用
四、原生java实现定时任务
4.1 创建定时任务类,实现TimerTask接口,重写run方法
/**
* 定时任务
*/
public class MyTimerTask extends TimerTask {
@Override
public void run() {
//定时任务执行体----里面可以编写定时任务需要执行的具体逻辑
System.out.println("定时任务执行!");
}
}
4.2 创建java定时器,并执行定时任务
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);
}
}
4.3 Spring中使用java定时器
在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);
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/116507.html